我是一个js的初学者,这几天被直接接见标识符和经由过程this接见标识符搞的头疼,因而斗胆勇敢的做了一个猜测:
1. 直接接见标识符是经由过程作用域链举行查找的。
2. 经由过程this接见标识符是经由过程原型链来查找的。
然后就最先试了起来!!!!
连系下面的代码来讲
var a = "abc";
var obj = {
a: "def",
display3: function () {
var a = "sssss";
console.log(a);
},
display4: function() {
console.log(this.a);
}
}
Object.prototype.a = "ghi";
function display1() {
// var = "hahaha";
console.log(a)
}
function display2() {
console.log(this.a);
}
display1(); // "abc"
display2(); // "abc"
obj.display3();
obj.display4();
// display2.call(obj); // "def"
// display1.call(obj); // "abc"
起首:
第一个:
挪用display1函数,经由过程作用域链来查找a。此时display1的作用域链为:display1的运动对象→全局运动对象,
所以找到了全局运动对象中的”abc”,假如在display1中有变量a,那末输出的则是这个变量的值。
第二个
挪用diplay2函数,经由过程原型链来查找a。由于this是基于当前的实行环境绑定的,所以this指向全局变量对象(也就是window),所以找到了”abc”并输出。
有意思的是,此时假如我删除window中定义的a=”abc”, 那末输出效果则是”ghi”. 因而回想了一下本身所学的学问,发明由于window对象是Global对象在浏览器中的表现,然后Global是js中的单体内置对象,那末彷佛它也应当继续自Object.prototype, 恩..根据我的猜测,输出效果为”ghi”是情理之中的。
第三个:
经由过程obj挪用display3函数,由于前面没有this,所以是经由过程作用域链举行查找的,此时display3的作用域链为display1的运动对象→全局运动对象,所以输出效果是”abc”, 一样,假如我再display3中定义了a,那末输出的则是这个a的值
第四个
经由过程obj挪用display4函数,由于前面有this,所以是经由过程原型链举行查找的,此时this指向的是obj,所以输出的效果是obj对象中”def”,假如我们删除obj中的a属性,那末输出效果则是Object.prototype中的”ghi”,假如再删除这个ghi,那末输出效果就是undefined了。
上面这些彷佛都相符逻辑,但是我又倏忽发明,当挪用display1时,假如删除了作用域链中每一个变量对象的a属性,那末输出效果则是”ghi”, 这个”ghi”是在Object.prototype中定义的,所以
综合了一下
1. 直接接见标识符是经由过程作用域链和原型链综合举行查找的。
2. 经由过程this接见标识符是经由过程原型链来查找的。
然后又涌现了一个题目:直接接见标识符的查找递次是 1:先查找作用域链前端的变量对象,然后再查找它的原型,然后再查找作用域链中下一个变量对象,然后再查找它的原型 照样 2: 一向查找作用域链中的变量对象,晓得window对象,再查找它的原型呢?
然后又倏忽发明,在挪用display1时,假如display1中没有定义a变量,接见到的则是window中的a = “abc”,而不是Object.prototype中的a = “ghi”.
所以再综合一下
1. 直接接见标识符的递次是按递次查找作用域链中的每一个变量对象直至全局变量对象,假如全局变量对象中没
有该变量,则沿着window对象的原型链举行查找。
2. 经由过程this接见标识符是经由过程原型链来查找的。
我去累死了,我也没想到本身写了这么多,从效果来看,应当是如许,不过也不晓得究竟是否是如许。。