共计 3964 个字符,预计需要花费 10 分钟才能阅读完成。
springboot 实战电商我的项目 mall4j(https://gitee.com/gz-yami/mall4j)
java 商城零碎源码
JavaScript 中的 this 绑定
在日常的开发中,咱们会常常应用 JavaScript 中的一个关键字:this,在常见的编程语言中,简直都有 this 这个关键字,然而 JavaScript 中的 this 和常见的变成语言中的 this 不太一样,
在常见的变成语言(java,c++ 等)中,this 通常只会呈现在类的办法中,而 this 指向它以后调用的对象,然而在 JavaScript 中,this 是更加灵便的,无论是它呈现的地位还是它代表的含意。
this 全局作用下的指向
这个问题非常容易答复,在浏览器中,this 的指向为全局对象 window
console.log(this) // window 对象
var name = "hhf"
console.log(this.name) // hhf
console.log(window.name) // hhf
然而,开发中很少间接在全局作用于上来应用 this,通常都是在函数中应用的
this 到底指向什么呢?
上面咱们通过一段代码,代码中,咱们定义一个函数,对他进行三种不同的形式进行调用,它产生了不同的后果
function foo() {console.log(this)
}
foo() // window 对象
const obj = {
name: "hhf",
foo: foo
}
obj.foo() // obj1
const obj2 = {}
foo.call(obj2) // obj2
从下面代码运行的后果咱们得出:
1. 函数在调用时,JavaScript 会默认给 this 绑定一个值;
2.this 的绑定和定义的地位(编写的地位)没有关系;
3.this 的绑定和调用形式以及调用的地位有关系;
4.this 是在运行时被绑定的
在 JavaScript 中,this 有四种绑定规定,别离是:
1. 默认绑定
2. 隐式绑定
3. 显式绑定
4.new 绑定
上面咱们别离对这四种绑定规定进行学习
默认绑定
默认绑定通常是在独立函数进行调用时进行绑定,独立函数调用咱们能够了解成没有被绑定到某个对象进行调用, 默认绑定在浏览器中指向的是 window,当为严格模式(use strict)的时候指向的是 undefined
// 案例一
function foo() {console.log(this)
}
foo() // window 对象
// 案例二
function foo(fn) {fn()
}
const obj = {
name: "hhf",
bar: function() {console.log(this)
}
}
foo(obj.bar) // window
显示绑定
显示绑定通常是某个对象对它进行调用,艰深来讲:谁调用就指向谁
function foo() {console.log(this.name);
}
const obj = {
name: "hhf",
bar: foo
}
obj.bar() // hhf
隐示绑定的另一种状况:
当有多层对象嵌套调用某个函数的时候,如 对象. 对象. 函数
,this 指向的是最初一层对象。
function foo() {console.log(this.name);
}
const person = {name: "person"}
person.foo = foo
const obj = {
name: "hhf",
bar: foo,
person: person
}
obj.person.foo() // person
显式绑定
在 JavaScript 中,所有的函数都能够应用 call、apply、bind 三个办法对函数的 this 进行绑定
应用形式的不同:call、apply 在函数调用时对它进行调用,bind 会返回一个新的函数
显示绑定的用处:防抖、节流等
call 函数的应用
call() 办法应用一个指定的 this 值和独自给出的一个或多个参数来调用一个函数。
它接管的参数为:第一个为绑定的 this,前面接上的为所调用的函数的参数
具体应用办法如下
// 根本应用
function foo() {console.log(this.name);
}
const obj = {name: "hhf"}
foo.call(obj) // hhf
// 传入参数
function foo(n, m) {console.log(this.name);
console.log(n, m)
}
const obj = {name: "hhf"}
foo.call(obj, "n", "m") // hhf n m
apply 函数的应用
apply 办法的语法和作用与 call() 办法相似,只有一个区别,就是 call() 办法承受的是一个参数列表,而 apply() 办法承受的是一个蕴含多个参数的数组。
具体应用办法如下
function foo(n, m) {console.log(this.name);
console.log(n, m)
}
const obj = {name: "hhf"}
foo.call(obj, ["n", "m"]) // hhf, n m
bind 函数的应用
bind 函数它所接管的参数和 call 函数一样,然而它会返回一个新的函数,新的函数的 this 会指向传入的对象
function foo(n, m) {console.log(this.name);
console.log(n, m)
}
const obj = {name: "hhf"}
const newFoo = foo.bind(obj, "n", "m")
newFoo() // hhf n m
new 绑定
new 是 JavaScript 中的一个关键字,当进行 new 操作调用函数时,会执行如下的操作
1. 函数外部会创立一个新的对象
2. 创立的对象的原型(__proto__)会指向函数的 prototype
3. 所创立的对象会绑定到该函数的 this 上
4. 如果函数没有其余返回值,会默认返回该对象
function Persion() {console.log(this)
}
new Persion(); // Persion {}
规定优先级
下面咱们学习了四种绑定规定,那么咱们可能会思考,如果一个函数在调用的时候应用了多种绑定规定,谁的优先级最高呢?
后果如下
1. 默认规定的优先级最低 p 毫无疑问,默认规定的优先级是最低的,因为存在其余规定时,就会通过其余规定的形式来绑定 this
2. 显示绑定优先级高于隐式绑定
function foo() {console.log(this.name)
}
const obj1 = {
name: 'obj1',
foo: foo
}
const obj2 = {name: 'obj2',}
obj1.foo.call(obj2) // obj2
3.new 绑定优先级高于隐式绑定
function foo() {console.log(this)
}
const obj1 = {
name: 'obj1',
foo: foo
}
const obj2 = {name: 'obj2',}
new obj1.foo() // foo {}
4.new 绑定优先级高于 bind
new 绑定和 call、apply 是不容许同时应用的,所以不存在谁的优先级更高
new 绑定能够和 bind 一起应用,new 绑定优先级更高 p 代码测试
function foo() {console.log(this)
}
const obj1 = {
name: 'obj1',
foo: foo
}
const newFoo = foo.bind(obj1)
new newFoo() // foo {}
箭头函数的 this
箭头函数是 ES6 中新增的一种函数的写法,然而箭头函数是不绑定 this 的,当在箭头函数中应用 this 时,它会随着它的作用域网上找,应用最近的作用域的 this 来应用
// 应用一般函数
const obj1 = {
name: 'obj1',
foo: function() {console.log(this)
}
}
obj1.foo() // obj1
// 应用箭头函数
const obj1 = {
name: 'obj1',
foo: ()=> {console.log(this)
}
}
obj1.foo() // window foo 的下层作用域为 window
// setTimeout 所传入的函数如果是一般函数,那么它绑定的是全局对象 window,如果传入的是一个箭头函数,那么它的 this 执行是它的下层作用域的 this 指向
const obj1 = {
name: 'obj1',
bar: function() {setTimeout(()=> {console.log(this)
})
}
}
obj1.bar() // obj1
上面咱们通过一道题,对刚刚所学的进行一个小练习
var name = "window"
function Person(name) {
this.name = name
this.obj = {
name: "obj",
foo1: function() {return function() {console.log(this.name)
}
},
foo2: function() {return ()=>{console.log(this.name)
}
}
}
}
var person1 = new Person("person1")
var person2 = new Person("person2")
person1.obj.foo1()()
person1.obj.foo1.call(person2)()
person1.obj.foo1().call(person2)
person1.obj.foo2()()
person1.obj.foo2.call(person2)()
person1.obj.foo2().call(person2)
输入后果为
/*
window
window
person2
obj
person2
obj
*/
springboot 实战电商我的项目 mall4j(https://gitee.com/gz-yami/mall4j)
java 商城零碎源码