JavaScript难点

602 阅读3分钟

执行环境:也称“环境”,定义变量或函数有权访问的其他数据,决定它们各自的行为,代码正则执行的时候才有,执行完就销毁。全局的执行环境关掉网页就销毁。

变量对象:每个执行环境都有与之关联的变量对象。环境中定义的所有变量和函数都保存在这个对象中。

变量对象差不多就是于作用域。p179底部

活动对象:执行环境是函数的变量对象也叫活动对象。

函数的执行环境和活动对象只有在函数执行的时候才有,执行完就被销毁掉了。函数声明的时候,就会预先创建包含除本身外的作用域链,存储在[[scope]]属性中。函数执行的时候,会为函数创建一个执行环境,然后复制[[scope]]中的对象,构建作用域链,并把自身的活动对象推入作用域链前端。

环境对象:直接包含这片环境的对象,如windows(环境是谁的,这个环境对象就指谁)。

this:函数执行的环境对象。

作用域链:指向变量对象的指针列表。

作用域只是保证了有权访问,但作用域链保证了有序访问。

作用域创建就存在,执行环境和变量对象执行了才有,执行完又销毁。

包含闭包的函数的活动对象要等闭包销毁后才销毁,但其执行环境和作用域链会被销毁。

由于[[Scope]]声明的时候就存在了,所以闭包的作用域链我们要看函数创建的那次外部函数执行完的活动对象结果,里面有什么就是什么。但是无论闭包还是函数的代码,不执行就相当于不存在,里面的代码要等调用的时候再去翻译比较好。

函数声明的时候就决定了作用域链,函数调用的时候才能决定this值。

this四大法则。

new四步曲。

原型:每个函数都有对应的原型对象。new创建的实例都共享原型中的属性和方法。函数中的prototype属性指向原型。原型中的constructor属性指向函数。实例中有[[prototype]]属性指向原型。

创建自定义类型的最佳方式是构造函数原型组合模式,共享的放在原型中,不共享的属性放在构造函数中。

原型链:让子类型的原型等于超类型的实例。

一个类型继承另一个类型的最佳方式是寄生组合式(让子类型的原型等于超类型原型的副本,再结合借用构造函数),目前最常用的是组合继承。

一个对象想得到相似的另一个对象,可以使用寄生式继承。


var j=1;function ou(){    var j=0;    console.log(inner(j)); //windows 这里只是传参,括号里的j会从当前变量对象中找}function inner(i){ //和这个括号里的i是不同的,这里的i是定义。语句中的找最近的变量对象中定义的    console.log(i);     return this;}ou();function ou1(){    function inner1(){        return this;    }    console.log(inner1()); //windows}ou1();var name="xiao";var obj={    name:"hong",    getName:function(){return this.name},    res:getName() //不能这么用,属性是无序的。会出现找不到getName错误}alert(obj.res)

写一个类似函数中的bind()

function bind(fn,o){    return function(arg){       return fn.call(o,arg);    };}function test(a){    test.b=a;  return this.b;}var b=1;alert(test(2)); //1var fn1=bind(test,test);alert(fn1(3)); //3