越日后面学愈加现基础的重要性,因此打算从新过一遍基础,以后出几个vue和react的实战教程。
ok,严归正传。javascript
this是执行上下文建立时肯定的一个在执行过程当中不可改变的变量。
总之记住一句话this的指向由以执行时候的上下文决定的而非定义时的上下文vue
看过一本书叫《JavaScript语言精粹》,里面把this的出现场景为4类,固然那是在es6出来以前,不过也能够表示基本的用法了,在es6出来以后出现箭头函数,因此一共是5种:java
let name = 'bob'; let obj = { name, getName(){ console.log(this.name); } }; console.log(obj.getName()); //=>bob
由于getName()属于对象obj,而且由obj进行调用,因此毫无疑问是指向obj这个对象,ok,咱们再看一个例子react
var name = 'jay'; var obj = { name:'bob' getName(){ console.log(this.name); } }; let t = obj.getName; console.log(t()); // => jay
如上,为何此次t函数打印出来的值是jay?excuse me?
其实要理解也好简单,当执行t()的时候(在非严格模式下)其实t实际上是属于全局对象(在浏览器环境)也就是window,而var name = 'jay'为全局变量,因此输出jay也不奇怪了。es6
var name = 'bob'; var obj = { name, getName:function(){ function otherName(){ return this.name; } console.log(otherName()); } }; obj.getName(); // =>bob
otherName随即是在obj的getName中定义的,可是它仍是一个普通函数,他的this其实和数组
var name = 'bob'; function otherName(){ return this.name; } console.log(otherName()); // =>bob
执行效果同样的,他的this的指向实际上是undefined,在非严格模式下,当this指向undefined的时候其实会自动转化成window对象(在浏览器中)。
ok,让咱们再看一种状况浏览器
var name = 'bob'; function otherName(){ "use strict" return this.name; } console.log(otherName()); // Uncaught TypeError: Cannot read property 'name' of undefined
这个时候会抛出一个错误,由于在严格模式下当this指针指向undefined的时候不会自动转化成window对象。app
首先什么是构造函数,其实能够用一句话去归纳:
构造函数其实就是用来新建对象的函数函数
JavaScript自己就为咱们定义了几个经常使用的构造函数,你确定认识 好比Function, Object, Array, Date等等,只不过咱们日常object,function都不是用new Function,new Object,而是用他的语法糖好比
var obj = {} 其实等同于 var obj = new Object();this
function Human(name,age,sex){ this.name = name; this.age = age; this.sex = sex; this.common = function(){ console.log('名字为'+this.name); } } var h = new Human('bob',25,'sex'); h.common(); // => 名字为bob
有new构造函数的就指向new完以后的新对象,此时的this指向的是他new出现来的对象h。
因为函数具备函数做用域,因此有时候咱们须要引用外层做用域的时候一般用的方法是call,apply,和bind这三兄弟
首先咱们来看看call,老样子先看代码
var a = { user:"bob", fn:function(){ console.log(this.user); } } var b = { user:'jay' } a.fn.call(b); // => jay
若是不调用call,咱们直接使用a.fn的话将会输出bob,由于fn这个方法是a这个对象定义出来的,因此this指向是a这个对象,可是当咱们使用了call以后this指针指向的对象就变成b了,因而乎也不难理解为何输出的user是jay了。
简介一下call的用法:
fn.call(obj,argument-1,argument-1,...)
是以obj这个对象去代替fn的this指针也就时fn的this指针指向obj,后面的argument-1,argument-1是形参
apply和call的用法基本相同,不一样点是apply调用传形参的时候穿的是数组或者是类数组,以下:
fn.apply(obj,[argument-1,argument-1,...])
至于bind和call或者apply的区别,我也举一个例子
var a = { user:"bob", fn:function(){ console.log(this.user); } } var b = { user:'jay' } var c = a.fn.bind(b); c(); // => jay
从上面这个例子能够得出一个结论:
其实call和apply方法,都是对函数的直接调用,可是bind()方法须要加上()来执行。
首先咱们先看一个例子:
var obj = {name:'bob'}; var name = 'jay'; var sayName = () => console.log(this.name); sayName(); // => jay sayName.call(obj); //jay
由上面的例子咱们能够看出来此时this指针在用call改变了以后指向的依然是全局对象(非严格浏览器环境中是window)而非obj。
ok,至此this指针的用法总结完毕。
以上this的用法都为我的总结,若有不当之处还请指出
转载请注明出处.