函数的四种调用模式与this的前世今生
// this 指向
// ①. 任何函数都有自己的this指向
// ②. this的指向和函数的调用模式相关,在函数没有调用的时候,仅仅是定义了函数,是不知道this的指向。
// 遇到this的问题,如何去分析
// 1. 分析这个this 是属于哪个函数的
// 2. 分析这个函数的调用模式是哪种
// 1. 函数调用模式, this ==> window
/*function fn(){
console.log(this);
}
// 函数名()
fn()*/
// 2. 方法调用模式, this ==> 调用方法的对象
/*var f = function () {
console.log(this);
}
var obj = {
abc: "abc",
fn: f
}*/
// 对象.方法名() 对象["方法名"]()
// obj.fn();
// obj["fn"]();
// 点语法、中括号来访问对象的方法,都是属于方法调用模式
// var arr = [f, 10, 20];
// arr[0](); // window arr
// 上面的this这么去理解
// var arr = {0: f, 1: 10, 2: 20};
// arr[0]();
// 3. 构造函数模式 ==> this ==> 实例对象
// function Person(){
// console.log(this);
// }
// var p = new Person();
// 4. 上下文模式
// 上下文调用模式 -- 方法借用模式
// call apply bind
// 任何函数都可以调用这三个方法
// 4.1 call
// 4.1.1. call 能够调用函数
/*function fn(){
console.log(1);
}
// () 有调用函数的作用
// fn();
fn.call();*/
// 4.1.2. call 可以改变函数内的this指向,call的第一个参数用来改变函数内的this指向
/*function fn2() {
console.log(this);
}
fn2.call({name:"xmg"})*/
// 4.1.3. call的参数是若干个,除了第一个参数外,其他的参数都是作为函数的实参
/*function fn3(n1, n2) {
console.log(this);
console.log(n1 + n2);
}
// fn3(10, 20); // window 30
fn3.call({name: "xmg"}, 100, 200);
fn3.call([10,20], 100, 200, 300, 400);*/
// 4.1.4. 如果call在调用的时候,没有传递任何参数,或者就传递了null/undefined,那么函数内的this指向为window的(了解)
/*function fn4() {
console.log(this);
}
fn4.call(undefined)*/
// 4.2 apply方法
// apply 方法和call方法作用是一样的,区别在于传参
// 语法: fn.apply(thisArg, 实参列表);
// 参数:
// thisArg ==> 修改fn函数内的this指向
// 实参列表 ==> 是一个数组或者是伪数组
/*var tangge = {
handsome: "very",
money: 1000000,
car: "劳斯莱斯",
liaomei: function(){
console.log("嘿, 妹子, 哥有" + this.car + ", 哥送你回家。");
}
}
var xmg = {
name: "小马哥",
car: "mobile"
}
tangge.liaomei.call(xmg);
tangge.liaomei.apply(xmg);*/
// 参数的区别
function fn(n1, n2){
console.log(this);
console.log(n1 + n2);
}
fn.call([10, 20, 30], 10, 20);
fn.apply({name: "xmg"}, [100, 200]); // apply的平铺性:会取出第二个参数中的每一项,作为函数的实参
// 4.3 bind方法
// 语法: var newFn = fn.bind(thisArg)
// 作用:bind方法会创建并返回一个新的函数,新函数内的this指向被固定成了bind的参数thisArg
// bind返回的函数和 fn 是一模一样的
function fn() {
console.log(this);
}
var fn2 = fn.bind({name: "lw"});
console.log(fn2.name);
// 长啥样
/*fn2 = function fn() {
console.log(this);
}*/
// console.log(fn == fn2); // false fn2和fn长的一样,但是是两个函数
// 虽然fn2 是函数调用模式,但是fn2 是bind创建出来的,fn2里面的this被固定了
// 固定的理解: 就是无论fn2是何种调用模式,this就已经固定了,固定了bind的thisArg参数
// fn2();
var obj = {
f: fn2
}
obj.f(); // 方法调用模式,但是fn2的this被固定了
// 总结:
// this 的指向和 函数的调用相关
// 模式:
// 1. 函数名() ==> window
// 2. 方法调用模式 对象.方法名() 对象["方法名"]() ==> 对象
// 3. 构造函数模式 ==> 实例对象
// 4. 上下文调用模式 ( call apply bind )
// 4.1. 任何函数都可以调用这三个方法
// 4.2. call的用法
// 4.2.1 可以用来调用函数
// 4.2.2 call的第一个参数用来改变函数内的this指向
// 4.2.3 除了第一个参数外,其他的参数用来作为调用函数的实参
// 4.3. apply的用法
4.3.1. apply和call的作用是相同的
4.3.2. apply的第二个参数是个数组或者是伪数组
4.3.3. apply的平铺性: 将第二个参数的每一项逐一的取出来,作为fn的实参
// 4.4 bind的用法
// 4.4.1. bind(): 不会调用函数
// 4.4.2. 创建并返回一个新的函数
// 4.4.2.1 新函数和fn长 的一样
// 4.4.2.2 新函数的this指向被固定了(无论新函数是何种调用模式,this都是不变的,固定指向了bind的thisArg参数)
上下文调用模式的区别
// bind 和call 、apply之间的区别“
// call、apply都可以调用函数
// bind不会调用函数的,会创建并返回一个新的函数
函数调用模式与this的前世今生
最新推荐文章于 2024-11-09 22:48:53 发布