一日,见“use strict”,冥想许久……html
系列列表:
从use strict看JS(一):this与箭头函数
从use strict看JS(二):函数传参模式与argumentsjava
use strict指js的严格模式,还没了解的看这里:Javascript 严格模式详解git
use strict有3点比较重要github
函数调用this为undefined面试
arguments。不容许对arguments赋值。禁止使用arguments.callee。arguments再也不追踪参数的变化babel
不用var声明不会提高成全局变量,而是报错闭包
use strict还有一些常人不易写错的,不归入写做范围:app
对象不能有重名的属性,函数不能有重名的参数函数
规定保留字。class, implements
回归正题,什么是函数调用?为什么严格模式函数调用要将this指向undefined?
首先牢记:js function有四种方式调用,每一种的this都不一样。
当函数被保存为对象的属性时,咱们称这个函数为方法。方法调用的this就绑定到该对象
var dog={ name:"doge", sayName:function(){ console.log(this.name); } } //输出doge,this绑定到了dog dog.sayName();
声明一个function而后调用。非严格模式this指向window,严格模式是undefined
function sayName(){ console.log(this); } function sayNameStrict(){ "use strict"; console.log(this); } //指向window sayName(); //开启严格模式,指向undefined sayNameStrict();
这在对象、对象继承用的比较多,经过new来使用,this指向new出来的新对象。
后面会有文章讲解new如何实现,到时候就会很清楚。
function Dog(name){ this.name=name; } var dog=new Dog("doge"); //this指向dog console.log(dog.name);
这类就是改变this,apply和call是很重要的,因此许多面试都会问,以后的文章咱们会看到它们的强大做用。
那就是函数调用了。这是js的一个设计错误,this应该绑定到外部函数的this变量,
这个错误便是“函数调用”this绑定的错误。严格模式规定,this不指向window了,但并无解决这个问题,因而箭头函数来了。
var dog={ name:"doge", sayName:function(){ return function(){ console.log(this); } } } // 此时是函数调用,this指向window dog.sayName()();
箭头函数怎么解决这个问题呢?其实用了闭包,改为下面这样,babel啥的也是这样作的。
var dog = { name: "doge", sayName: function sayName() { var _this = this; return function () { console.log(_this); }; } };
那若是嵌套了多层箭头函数?对闭包来讲是同样的
var dog={ name:"doge", sayName:function(){ return ()=>{ return ()=>{ console.log(this); } } } }
至关于
var dog = { name: "doge", sayName: function sayName() { var _this = this; return function () { return function () { console.log(_this); }; }; } };
那若是函数的属性就是箭头函数?没有这样用的!你会拿到window
var dog={ name:"doge", sayName:()=>{ console.log(this); } } // this指向window,由于箭头函数 dog.sayName();
这是一本书,文末有连接。
the good parts说过:js语言有些地方设计得很差,因而后来的标准不断地补坑。
the good parts又说过:js 函数调用this绑定到window是一个设计错误
等等,严格模式函数调用this为什么指向undefined??
首先,不应指向window,因此换一个。
其次,指向undefined有一个好处,构造函数通常不要直接运行,那要是强行运行呢?this指向window会给window添加许多属性,有扰乱命名空间之嫌,指向undefined以后,你强行运行我就强行报错!
function Dog(name){
this.name=name;
}
//会给window增长name属性,改为严格模式就会TypeError
Dog("doge");
固然,use strict不能解决全部问题,因此有了箭头函数