function sayHello() {
console.log(this);
}
sayHello();
// 在浏览器环境下,会输出window对象,表明函数内部this指向了window(全局对象)
const person = {
name: 'Alice',
sayHello: function () {
console.log(`Hello, my name is ${this.name}`);
}
};
person.sayHello();
// 这里sayHello函数作为person对象的方法被调用,函数内部的this
就指向person对象,所以会输出 "Hello, my name is Alice"
function Person(name) {
this.name = name;
console.log(this);
}
const personInstance = new Person('Bob');
// 这里通过new调用Person函数创建实例,在Person函数内部this指向新创建的personInstance对象,会输出这个实例对象的相关信息
const person = {
name: 'David',
createArrowFn: function () {
return () => {
// 这里箭头函数的this继承自外层的createArrowFn函数的this,而createArrowFn函数里this指向person对象,所以箭头函数里this也指向person对象
console.log(this.name);
};
}
};
const arrowFn = person.createArrowFn();
arrowFn(); // 输出 "David"
使用call方法调用函数时,第一个参数为this指定的值
call方法的其余参数会依次自动传入函数作为函数的参数
// call方法改变this指向
function fn(a,b){
console.log(this,a,b)
}
let obj={uname:'牛牛',age:18}
fn.call(obj,666,999)
//fn函数调用call方法改变this指向
//call会让fn函数在执行过程中改变this指向,此时this指向obj,同时将666,999传给a、b
let obj={
uname:'牛牛',
age:18,
study:function(){
console.log(this)
}
}
let o={uname:'萌萌',age:17}
obj.study.call(o)//此时obj中的study方法的指向变为o这个对象
function add(a, b) {
return a + b;
}
// 传递两个参数
const result = add.call(null, 1, 2);
console.log(result); // 输出: 3
第一个参数为this指定的值
apply方法的第2个参数,必须是一个数组(或类数组对象)
类数组对象是指具有 length
属性且元素可通过数字索引访问的对象,例如 { 0: 'a', 1: 'b', length: 2 }
。
不用改变this指向,所以第一参数为null
在使用 apply
方法时,函数只会考虑其参数列表中定义的参数数量,对于超出函数参数数量的数组元素,它们会被忽略,并且 length
属性不会作为参数传递给函数
function fn(a,b){
console.log(this,a,b)
}
let obj={uname:'牛牛',age:18}
fn.apply(obj,[666,999])//第二个参数虽然是数组,但是内容与函数的形参一一对象,数组里有几个值,就看函数有几个形参
// 求数组最大值方法
let arr=[1,2,3,4,5,6]
let re=Math.max.apply(null,arr)
//不用改变this指向,所以第一参数为null
//直接Math.max(arr)会报错,因为Marh.max()是个函数,所以可以调用apply方法将数组传过去
console.log(re)
function add(a, b, c) {
return a + b + c;
}
// 使用类数组对象作为参数
let arrayLike = { 0: 4, 1: 5, 2: 6, length: 3 };
let result2 = add.apply(null, arrayLike);
console.log(result2); // 输出 15
this
值会被永久绑定到 bind
方法的第一个参数上bind(person)
将 greet
函数的 this
绑定到 person
对象上。这样,无论 greetFn
如何调用,其 this
始终指向 person
。bind
操作需要作用在函数对象上,而不是普通对象上。const person = {
name: 'Alice',
greet: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
const greetFn = person.greet.bind(person);
greetFn(); // 输出 "Hello, my name is Alice"
function add(a, b, c) {
return a + b + c;
}
const addFive = add.bind(null, 5);
console.log(addFive(2, 3)); // 输出 10
bind(null, 5)
创建了一个新函数 addFive
,其中第一个参数 a
已经被预定义为 5
。调用 addFive(2, 3)
时,2
作为 b
,3
作为 c
传递给 add
函数
call
和 apply
是立即调用函数并设置 this
及参数,而 bind
只是创建一个新函数,并不立即调用