一:this关键字
在JavaScript中,this
是一个特殊的关键字,它在函数执行时绑定到不同的值,取决于函数的调用方式。this
的值通常是调用函数的对象。
this
的值可以是以下几种情况:
- 全局上下文中的
this
: 当函数在全局上下文中被调用时,this
指向全局对象(在浏览器中是window
对象)。console.log(this); // 输出全局对象(在浏览器中是 window 对象)
- 函数作为对象的方法调用时的
this
: 当函数作为对象的方法调用时,this
指向调用该方法的对象。var myObject = { name: "sw", sayHello: function() { console.log("Hello, " + this.name + "!"); } }; myObject.sayHello(); // 输出 "Hello, sw!"
在上面的示例中,
sayHello
方法中的this
指向myObject
对象。 -
构造函数中的
this
: 当函数作为构造函数使用时,this
指向新创建的对象function Person(name) { this.name = name; } var person = new Person("John"); console.log(person.name); // 输出 "John"
在上面的示例中,
Person
构造函数中的this
指向新创建的person
对象。 - 使用
call
、apply
或bind
显式指定this
: 可以使用call
、apply
或bind
方法来显式指定函数执行时的this
值。 - this不看它是哪个函数的也不看它是哪个对象的 而看它所在的函数是哪个对象调用的。
obj.fn()//obj
fn()//window
arr[0]()//arr
obj.x.y()//obj.x
(函数)()//window
fn()(3) //window
fn()()(4) //window
fn()[0]()//fn()返回的数组
fn()[0]()(99)//window
看不出来了 一般都是window
实例练习:
var obj1 = {
name: "sw",
say: function () {
console.log(this)
}
}
var fn = obj1.say
var obj2 = {
name: "tom",
say: function () {
fn()
}
}
obj2.say() //window
var obj={name:"sw"}
console.log(obj)
obj.age=20
var obj = {
name: "zhangsan",
sayName: function () {
console.log(this.name);
}
}
var wfunc = obj.sayName;
obj.sayName();
wfunc();
var name = "lisi";
obj.sayName();
wfunc();//{name: 'sw'}
zhangsan
lisi
zhangsan
lisi
二:this劫持-call-apply-bind
call
在JavaScript中,call
是一个函数的方法,它允许你显式地指定函数执行时的 this
值,并且可以传递参数给函数。
call
方法的语法如下:
function.call(thisArg, arg1, arg2, ...)
thisArg
:要将函数绑定到的对象,即函数执行时的this
值。arg1, arg2, ...
:要传递给函数的参数。
实例练习:
function fn(){
console.log(this)
}
var obj={life:1}
obj.x=fn
fn.call(obj)
fn.call([2,6,4])
console.log(fn.length)//{life: 1, x: ƒ} [2, 6, 4] 0
function fn(a,b){
console.log(this,a,b,arguments)
}
fn.call([10,20,30],90,80,70)
apply
在JavaScript中,apply
是一个函数的方法,它允许你显式地指定函数执行时的 this
值,并且可以传递参数给函数。与 call
方法不同的是,apply
方法接受一个参数数组而不是逐个传递参数。
apply
方法的语法如下:
function.apply(thisArg, [argsArray])
thisArg
:要将函数绑定到的对象,即函数执行时的this
值。argsArray
:一个数组,包含要传递给函数的参数。
实例练习:
var person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person1 = {
firstName: "bill",
lastName: "gates",
}
person.fullName.apply(person1); //bill gates
var person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"Bill",
lastName: "Gates"
}
person.fullName.apply(person1, ["Oslo", "Norway"]);
bind
在JavaScript中,bind
是一个函数的方法,它创建一个新的函数,将原函数绑定到指定的对象,并返回这个新函数。与 call
和 apply
方法不同的是,bind
方法不会立即执行函数,而是返回一个绑定了指定上下文的新函数。
bind() 用于将函数内的this指向目标对象。
有时必须使用 bind() 方法来防止丢失 this。
bind
方法的语法如下:
function.bind(thisArg, arg1, arg2, ...)
thisArg
:要将函数绑定到的对象,即函数执行时的this
值。arg1, arg2, ...
:要传递给函数的参数。
实例练习:
var a = {
b: function() {
var func = function() {
console.log(this.c);
}
func.bind(this)();
},
c: 'hello'
}
a.b(); // hello
function f(y,z){
return this.x+y+z;
}
var m = f.bind({x:1},2);
console.log(m(3)); // 6
三:new关键字
在 JavaScript 中,new
是一个关键字,用于创建一个对象实例。它用于调用构造函数,并创建一个新的对象,该对象继承了构造函数的属性和方法。
使用 new
关键字创建对象的过程如下:
- 创建一个空对象。
- 将新创建的对象的原型指向构造函数的原型。
- 将构造函数的
this
值绑定到新创建的对象。 - 执行构造函数中的代码,初始化新对象的属性。
- 如果构造函数没有显式返回一个对象,则返回新创建的对象。
实例练习:
function fn(a) {
this.life = 1
this.a = a
return 200
}
var f1 = new fn(100)
console.log(f1) //fn {life: 1, a: 100}
function Person (name,age){
this.name = name;
this.age = age;
this.say = function () {
console.log("I am " + this.name)
}
}
let person1 = new Person("Star",20);
console.log(person1.name);
console.log(person1.age);
person1.say(); //star 20 i am star
四:原型对象
在 JavaScript 中,每个对象都有一个原型对象(prototype)。原型对象是一个普通的对象,它包含了共享的属性和方法,可以被其他对象继承和共享。
每个 JavaScript 对象都有一个 __proto__
属性,它指向该对象的原型对象。
原型对象的作用是实现对象之间的继承。
步骤:
1.创建对象==> 创建一个空对象,然后给这个空对象添加一个属性 __proto__。这属性保存了一个对象这个对象就是构造函数的prototype属性中保存的那个对象
2.调用函数
3.this指向创建的对象
4.表达式生成结果(返回的引用数据 创建的对象)
实例练习:
function fn() {
this.a = 20
}
fn.prototype.b = 100
var f1 = new fn()
console.log(f1.a)
console.log(f1.b)
console.log(f1.__proto__.b)
f1.__proto__.b = 300
var f2 = new fn()
console.log(f2.b)//20 100 100 300