// call,apply和bind都可以改变函数的this指向
let obj1 = {
name:"obj1",
fn1(param){
console.log(this.name,param,"-----");
}
}
let obj2 = {
name:"obj2",
fn1(param){
console.log(this.name,param,"++++++");
}
}
//call、apply、bind的作用是改变函数运行时this的指向
//正常调用
// obj1.fn1("param1") //输出obj1 param -----
//call apply的第一参数都是this绑定的对象,如果第一个参数不传,或者传null,undefined.那么this的指向为window
//区别点:call的第二个参数传入的是参数列表,而apply传入的是数组
//参数列表:"param","param1","param2" 数组:["param","param1","param2"]
//call apply则立即调用
//bind会返回一个有this指向的新函数 用于后续调用
obj1.fn1.call(obj2,"param") //输出obj2 param -----.是因为call把fn1里面的this指向指向了obj2
// 错误Uncaught TypeError: obj1.call is not a function.调用call的是需要一个函数
// obj1.call(obj2,"param")
obj1.fn1.apply(obj2,["param3"]) //输出:obj2 param3 -----
//bind
let newFn = obj1.fn1.bind(obj2,"param4")
console.log(newFn); /*输出:f fn1(param){
console.log(this.name,param,"-----");
}
注意虽然看着和fn1的函数一样,但这个新函数的this指向已经发生了变化*/
newFn() //输出: obj2 param4 -----
obj1.fn1("param") //输出:obj1 param ----- 可以看出原来的函数不受影响的
练习
function a(){
console.log(this
);
}
function b(){}
var c = {name:"call"}
a.call() //第一个参数不传 则指向window
a.call(null) //指向window
a.call(undefined) //指向window
a.call(1) //Number {1}
a.call("") //String {''}
a.call(true) //Boolean {true}
a.call(b) //ƒ b(){}
a.call(c) //{name: 'call'}
// ------------------------
function class1(){
this.name = function(){
console.log("我是class1的内部方法");
}
}
function class2(){
//此行代码执行后,当前的this指向了class1(也可以说class2继承了class1)
//理解:class2中的this指向了class1,那么class2的实例可以用class1函数中的所有属性和方法
//this的这个指向相当于oc中的isa指针
class1.call(this)
}
var f = new class2()
//class2自身没有这个方法.但this指向了class1,class1中有.就是用了class1中的
f.name() //我是class1的内部方法
//-------------
function eat(x,y){
console.log(this,"----");
console.log(x+y);
}
function drink(x,y){
console.log(this,"++++");
console.log(x-y);
}
eat.call(drink,3,2); //输出结果5.注意:调用eat.call(...)只是改变了函数内部的this指向.
//----------------
function Animal(){
this.name="animal";
this.showName=function(){
console.log(this.name);
}
}
function Dog(){
this.name="dog";
}
var animal=new Animal();
var dog=new Dog();
animal.showName.call(dog);
//输出dog.把animal.showName()的内部this的指向指到了Dog这个对象
//或者另外一种理解:animal把showName方法放到了dog对象内部
// ---------------
//类似这种否早函数中绑定this的,简单理解直接把调用这的属性好人方法复制拷贝到了当前对象中
function Animal(name){
// 通过 Animal.call(this,name);之后,这里的this就指向了Dog.从此就有了dog.name,dogshowName()这些属性和方法
console.log(this,"----");
this.name=name;
this.showName=function(){
console.log(this.name);
}
}
function Dog(name){
Animal.call(this,name);
/*
Animal.call(this,name);
也相当于把Animal中的这些放到这里
this.name=name;
this.showName=function(){
console.log(this.name);
}
*/
}
var dog=new Dog("Crazy dog");
dog.showName(); ///Crazy dog
//--------bind和call.apply的用法最大的区别是,bind是返回了一个新的函数
var bar=function(){
console.log(this.x);
}
var foo={
x:3
}
bar();
bar.bind(foo)();
/*或*/
var func=bar.bind(foo);
func();
//输出:
//undefined
//3
网友评论