--昨天刚差不多学完vue,想重构个CNode中文社区(这好像是每个学完Vue都准备练手的项目),可是一点头绪没有啊!逛了几个大佬的教程,还是没有得到我想要的。那时候图书馆也快关门了,就想着今天有空写写。今天早上又去答辩了课程设计-B树,老师不按常理问问题搞得我也挺烦的。说回那个CNode,自己技术栈还是差了点,有空补补技术栈再写一篇小白版CNode重构教程吧。
开心的是,今天逛论坛看到一个老哥一年前发的两道题,感觉挺有意思的。主要涉及的也是作用域和this的语法。正好我之前也读过《你不知道的javas》上卷(好书啊!!!),强烈推荐这一系列书,在你学完JS迷茫期的时候读读这系列书,你会发现很多JS有意思的东西。学习就是这样,学的越多感觉自己懂得越少。下面分享下那两道题,顺便用我比较浅显的语言分析一下。
第一题:关于this绑定的问题。
var length = 10;
function fn() {
console.log(this.length)
};
var obj = {
length: 5,
method: function (fn) {
fn();
arguments[0]();
fn.call(obj, 14);
}
};
obj.method(fn, 1);//10,2,5
先来一些知识铺垫:
this的绑定机制:
简单来说就是this的绑定是在运行时绑定的,他取决于函数的调用方式。函数调用的时候会有一个记录,这个记录里面就存有this属性。简单来说,就是一般this指向什么,取决于函数在哪里被调用的!
this的三种绑定形式:
1.默认绑定
当this运用了默认绑定的时候,此时this就指向全局对象。你也可以这么理解,函数是在全局作用域被调用,理所应当的指向全局对象。
2.隐式绑定
当函数调用拥有上下文对象的时候,通俗的讲就是是否被某个对象拥有。
看下面这个例子
function foo(){
console.log( this.a );
}
var a=2;
var obj = {
a:1,
foo:foo
};
obj.foo();//1
foo();//2
这里,foo被obj内部的foo属性引用,obj.foo()可以这么理解,调用obj内的foo,这时的foo调用被obj拥有,所以this当然指向obj。我用的Foo函数都是我的属性,this不应该指向我吗?3.显式绑定
显式绑定就比较容易发现,一般来说有:call,apply绑定;bind绑定;函数调用时一个类似bind绑定的参数绑定;new绑定
优先级:new > 显式 > 隐式 >默认。
接着看上面的题。
大致就是,定义了一个全局的length为10,一个函数声明fn输出this.length,一个对象包含一个length为5,有一个方法返回fn(),arguements[0](),fn.call(obj,14);最后调用这个方法,问我们输出的是什么。
分析:
第一步:obj.method(fn,1),就是调用obj的method,然后传入参数fn,1。此时的arguments为{‘0’:fn,'1':1}
第二步:fn()这就是在全局作用域调用fn(),虽然他在method中,但是这只是在method下调用了fn(),所以this指向全局对象,第一个输出10
第三步:arguements[0](),arguments[0] = fn,所以就是调用arguements中的fn,此时fn的this就隐式绑定到了argums,这个等价于fn.call(arguments)。那么为什么会输出2呢?MDN上对arguments的描述:The arguments object is not an Array. It is similar to an Array, but does not have any Array properties except length. 懂了吧?这里输出的就相当于arguments.length,两个参数当然就是2了。
第四步:fn.call(obj, 12)简单了啊,显式绑定啊,this绑定到obj,输出5!
this绑定机制那么复杂,那么容易让人误解,所以ES6出了胖箭头,就把this定义在词法作用域。简单改写一下上面的函数
var length = 10;
fn = ()=>{
console.log(this.length)
}
var obj = {
length: 5,
method: function (fn) {
fn();
arguments[0]();
fn.call(arguments);
fn.call(obj, 14);
}
};
obj.method(fn, 1);//10,10,10
胖箭头=>把this绑定到了fn,fn是什么它就是什么,这里fn是个全局对象,所以this也指向全局对象。有点像任他风吹雨打 我自岿然不动的感觉。