js -this,new、call、apply、bind 相关面试题
this问题
在es5中,在函数定义时是无法确定this的指向的,只有在运行的时候才知道它的指向,实际上this的指向是指向调用它的那个对象
例子1
function a() { var user = '1' console.log(this.user) // undefined console.log(this) // window } a()
这时是window调用,所以这时this指向的是window
例子2
var o= { user = "1", fn: function() { console.log(this.user) // "1" } }
o.fn()
这里的this指向的是对象o,因为你调用这个fn是通过o.fn()执行的,那自然指向就是对象o
例子3
var o = { user: "1", b: { user: "2", fn: function () { console.log(this.user) // "undefined" console.log(this) // window } } } var j = o.b.fn; j()
这里this指向的是window,his永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,例子3中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window
构造函数版this
function Fn () { this.user = 'ceshi' } var a = new Fn(); console.log(a.user) // 'ceshi'
这里之所以对象a可以点出函数Fn里面的user是因为new关键字可以改变this的指向,将这个this指向对象a,为什么我说a是对象,因为用了new关键字就是创建一个对象实例,理解这句话可以想想我们的例子3,我们这里用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。
new到底干了什么事呢?
1:创建一个空的对象,并且继承了原型链上的属性和方法
2:执行构造函数,如果没有返回值则将this指向刚刚创建的新对象,如果返回一个对象,则this是指向返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
3:返回新对象;
更新一个小问题当this碰到return时
学习链接https://www.cnblogs.com/pssp/p/5216085.html
call apply
call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
apply方法:
语法:apply([thisObj[,argArray]])
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象
function add(a,b) { alert(a+b); } function sub(a,b) { alert(a-b); } add.call(sub,3,1);
这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4); // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。
function Animal(){ this.name = "Animal"; this.showName = function(){ alert(this.name); } } function Cat(){ this.name = "Cat"; } var animal = new Animal(); var cat = new Cat(); //通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。 //输入结果为"Cat" animal.showName.call(cat,","); //animal.showName.apply(cat,[]);
call 的意思是把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat
function Animal(name){ this.name = name; this.showName = function(){ alert(this.name); } } function Cat(name){ Animal.call(this, name); } var cat = new Cat("Black Cat"); cat.showName();
Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了吗,Cat对象就能够直接调用Animal的方法以及属性了.
call和apply方法通常被用来实现类似继承一样的功能,以达到代码复用的功效。它们的区别主要体现在参数上