js的预解析
首先介绍一些即将用到的概念:
作用域链:
当某个函数第一次被调用时,会创建一个执行环境及相应的作用域链,并把作用域链赋值给一个特殊的内部属性Scope,作用域链包括了一系列活动对象,第一位的是当前函数的this,arguments和其他命名参数的值来初始化的对象。然后从内向外的顺序创建活动对象,直到全局作用域对象。
总结一下他们的关系:当函数作为构造函数调用时,比如:
function Person(){} Person.prototype.sayName=function(name){alert(name)} var person1=new Person(); person1.sayName("wenber");
在创建函数Person时:该函数Person就有一个prototype属性,即Person.prototype,它指向Person的原型对象Prototype。(这里有点绕,可以这么理解,Person的一个属性叫做prototype,这个属性又指向一个对象叫做Prototype,与此同时,这个叫做Prototype的对象它也有个属性叫做constructor,它指向了Person本身;
当实例化对象Person,也就是执行了构造函数Person,该实例person1又具有一个叫做_proto_的属性,它指向Person的原型对象Prototype(记住不是Person本身)。
如图:
1,js是顺序执行的,下面这个大家肯定没有异议
test();// 哈哈
function test(){
alert("哈哈");
}
但是在C语言中,这样就不行了,C语言要求函数必须先声明后调用,那是什么原因让js有如此能力先调用而后声明了?ok,这说明js肯定是在调用函数之前就将函数放入内存中了,这种简单的机制就是我们今天要说的---js预解析
2,变量的预解析,看如下代码
alert(a);//undefined var a="test";
和函数声明一样,变量的声明也会在一开始就被放入内存中了,但是并没有赋值,所以在它赋值之前,它的值就是undefined;
3,变量和函数重名,看如下代码
alert(a); //function(){ return "function"}
var a="var";
function a(){ return "function" }
alert(a); // var
这个就说明了,重名时,函数名优先级高于变量名
4,js的预解析是在程序进入一个新的环境时,把该环境里的变量或函数预解析到它们能调用的环境中。即每一次预解析的单位是一个执行环境。代码如下
function a(){ var b="function" } alert(b);//报错 b is not defined
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。