购物网站开发的需求分析网站建设栏目添加
news/
2025/9/30 7:04:54/
文章来源:
购物网站开发的需求分析,网站建设栏目添加,网站程序开发公司,什么叫网站优化一、调用位置
在理解this的绑定过程之前#xff0c;首先要理解调用位置#xff1a;调用位置就是函数在代码中被调用的位置#xff08;而不是申明的位置#xff09;。只有仔细分析调用位置才能回答这个问题#xff1a;这个this到底引用的是什么#xff1f;
function foo…一、调用位置
在理解this的绑定过程之前首先要理解调用位置调用位置就是函数在代码中被调用的位置而不是申明的位置。只有仔细分析调用位置才能回答这个问题这个this到底引用的是什么
function foo() {console.log(foo)// 当前调用栈是: bar// 因此当前调用位置在bar中
}function bar() {console.log(bar)// foo当前调用位置foo()// 当前调用栈是: bar// 因此当前调用位置在bar中
}function baz() {console.log(baz)// bar当前调用位置bar()// 当前调用栈是: baz// 因此当前调用位置是全局作用域
}// baz当前调用位置
// 全局作用域
baz()二、绑定规则
1、默认绑定非严格模式独立函数调用
const a 2
function foo() {console.log(this.a)
}
foo() // 2
// foo() 在这里直接食用不带任何修饰的函数引用进行调用因此只能使用默认绑定调用位置为全局作用域因此this默认绑定到全局作用域。2、隐式绑定调用位置是否有上下文或者说是否被某个对象拥有或者包含
当函数引用有上下文对象时隐式绑定规则会把函数调用中this绑定到这个上下文对象上。
function foo() {console.log(this.a)
}
const obj {a: 2,foo: foo
}
obj.foo() // 2// 注意 首先需要注意的是foo()的声明方式及其之后是如何北方做引用属性添加到obj中的。但是无论是直接在obj中定义还是先定义在添加为引用属性这个函数严格来说都不属于obj对象。
// 然而调用位置会使用obj上下文来引用函数因此你可以说函数被调用时obj对象‘拥有’或‘包含’它。// 当函数引用有上下文对象时隐式绑定规则会把函数调用中this绑定到这个上下文对象上。对象属性引用链中只有 最顶层 或者说 最后一层 会影响调用位置
function foo() {console.log(this.a)
}
const obj1 {a: 2,foo: obj2
}
const obj2 {a: 42,foo: foo
}
obj1.obj2.foo() // 42隐式丢失一个最常见的this绑定问题就是 被隐式绑定的函数 会丢失绑定对象也就是说它会引用默认绑定从而把this绑定到全局对象或者undefined上取决于是否是严格模式。
function foo() {console.log(this.a)
}
const obj {a: 2,foo: foo
}
const bar obj.foo // 函数别名
const a 我是全局对象
bar() // - 我是全局对象
// 虽然bar是obj.foo的一个引用但是实际上他引用的是foo函数本身因此此时的 bar() 相当于 foo(), 是一个不带任何修饰的函数调用因此应用了默认绑定function foo() {console.log(this.a)
}
function doFoo(fn) {// fn其实引用的是foofn() // --调用位置
}
const obj {a: 2,foo: foo
}
const a 我是全局对象
doFoo(foo) // - 我是全局对象
// 参数传递其实就是一种隐式赋值因此我们传入函数时也会被隐式赋值所以结果和上一个例子一样// 如果把函数传入语言内置的函数而不是自定义的函数会怎么样呐结果是一样的没有区别
function foo() {console.log(this.a)
}
const obj {a: 2,foo: foo
}
const a 我是全局对象
setTimeout(obj.foo, 100) // - 我是全局对象// JavaScript环境中内置的setTimeout()函数实现和下面的代码类似
function setTimeout(fn, delay) {// 等待delay毫秒fn() // --调用位置
}3、显式绑定
function foo() {console.log(this.a)
}
const obj {a: 2,
}
foo.call(obj) // - 2
// 通过foo.call(...)可以在调用foo时强制把它绑定到obj上// 思考下面代码输出什么
const b 我是全局对象
function foo() {console.log(this.b)
}
const obj {b: 2,foo: foo
}
const bar function(fn) {fn()
}
bar.call(obj, foo) // - 我是全局对象// 显然通过这种方式还是无法解决绑定丢失问题3.1、硬绑定
function foo() {console.log(this.b)
}
const obj {b: 2,
}
const bar function() {foo.call(obj)
}
bar() // - 2
// 硬绑定的bar不能再修改它的this
bar.call(window) // - 2由于硬绑定是一种非常常用的模式。所以在es5中提供了内置的方法Funtion.prototype.bind bind(…)会返回一个硬编码的新函数它会吧参数设置为this的上下文并调用原始函数
function foo(something) {console.log(this.a, something)return this.a something
}
const obj {a: 2,
}
const bar foo.bind(obj)
const b bar(3) // - 2 3
console.log(b) // - 54、new绑定 使用new来调用函数或者说发生构造函数调用时它会自动执行下面的操作
创建构造一个全新的对象这个新对象会被执行[[原型]]链接将这个对象的_proto_指向其构造函数的原型这个新对象会绑定到函数调用构造函数的this如果函数没有返回其他对象那么new表达式中的函数调用会自动返回这个新对象
function foo(a) {this.a a
}
const bar new foo(2)
console.log(bar.a) // - 2三、优先级
如果某个调用位置同时使用四条规则那谁的优先级更高呢 1、隐式绑定与显式绑定谁的优先级更高
function foo() {console.log(this.a)
}
const obj1 {a: 2,foo: foo
}
const obj2 {a: 3,foo: foo
}
obj1.foo() // - 2
obj2.foo() // - 3obj1.foo().call(obj2) // - 3
obj2.foo().call(obj1) // - 2// 可以看到显式绑定优先级高于隐式绑定2、隐式绑定与new绑定谁的优先级更高
function foo(something) {this.a something
}
const obj1 {foo: foo
}
const obj2 {}obj1.foo(2)
console.log(obj1.a) // - 2obj1.foo.call(obj2, 3)
console.log(obj2.a) // - 3const bar new obj1.foo(4)
console.log(obj1.a) // - 2
console.log(bar.a) // - 4// 可以看到new绑定的优先级高于隐式绑定3、new绑定与显式绑定谁的优先级更高 new和call/apply无法一起使用因此无法通过 new foo.call(obj1)来直接进行测试但是我们可以使用硬绑定来进行测试
function foo(something) {this.a something
}
const obj1 {}
const bar foo.bind(obj1)
bar(2)
console.log(obj1.a) // - 2const baz new bar(3)
console.log(obj1.a) // - 2
console.log(baz.a) // - 3// 可以看到new绑定的优先级高于显式绑定四、判断this步骤
现在我们可以根据优先级来判断函数在某个调用位置引用的式哪条规则
函数是否在new中调用new绑定如果是的话this绑定的是新创刊的对象。 const bar new foo()函数是否通过callapply显示绑定或者bind(硬绑定)调用如果是的话this绑定的式指定对象。 const bar foo.call(obj2)函数是否在某个上下文对象中调用隐士绑定如果是的话this绑定的是那个上下文对象 const bar obj1.foo()如果都不是的话使用默认绑定。如果在严格式模式下就绑定到undefined,否则绑定到全局对象 const bar foo()
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/922559.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!