分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

You Don't Know JS: this & Object Prototypes( 第2章 this)

发布时间:2023-09-06 02:17责任编辑:彭小芳关键词:暂无标签

this is a binding made for each function invocation, based entirely on its call-site (how the function is called).

this是为函数被引用而创建的绑定!完全地基于函数如何被调用/函数的call-site!


Call-site

:the location in code where a function is called 

call-stack: 调用函数的堆栈。(函数的调用链条,函数的call-site的移动形成了stack。)

The call-site  is in the invocation before the currently executing function.

function baz() { ???// call-stack is: `baz` ???// so, our call-site is in the global scope ???console.log( "baz" ); ???bar(); // <-- 下一个调用位置是‘bar‘}function bar() { ???// call-stack is: `baz` -> `bar` ???// so, 我们的call-site是在‘baz‘内。 ???console.log( "bar" ); ???foo(); // <-- call-site for `foo`}function foo() { ???// call-stack is: `baz` -> `bar` -> `foo` ???// so, our call-site is in `bar` ???console.log( "foo" );}baz(); // <-- call-site for `baz`

在浏览器inspector中,可以使用debugger工具观察call-site。

function baz() { ???console.log(this); ???console.log( "baz" ); ???bar(); // <-- call-site for `bar`}function bar() { ???console.log(this) ???console.log( "bar" ); ???foo(); // <-- call-site for `foo`}function foo() { ???console.log(this); ???console.log( "foo" );}baz();
最后的结果是3个this都指向window对象。

Nothing But Rules

在函数执行期间,call-site如何决定this指向哪里?

有:4条法则!及这4条法则的优先级。

default Binding

第一条法则来自最常用的函数调用: 独立的函数引用。(没有其他法则影响的函数)

function foo() { ???console.log( this.a );}var a = 2;foo(); // 2

this指向全局对象,变量a是全局对象的属性。

如果是严格模式,this指向undefined!

第一条:this绑定完全基于call-site,非严格模式下,全局对象是默认的绑定对象。

注意:不要混用严格模式和非严格模式!

Implicit Binding

第2条:如果call-site有一个context对象,也涉及一个拥有或包含的对象。

function foo() { ???console.log( this.a );}var obj = { ???a: 2, ???foo: foo};obj.foo(); // 2 ??因为obj就foo()调用的this, 所以this.a等同于obj.a

当有一个content object 拥有一个函数引用时,
Implicit Binding Rule 就是那个对象应当拥有这个函数调用的this绑定

??:Only the top/last level of an object property reference chain matters to the call-site.

也就是说假如有:  obj1.obj2.obj3.foo(), 调用foo()函数的this绑定在obj3上。

Implicitly Lost

当一个Implicit bound 函数丢弃了context对象的binding, 就会使用默认binding。或用全局对象,或undefined(use strict)。

function foo() { ???console.log( this.a );}var obj = { ???a: 2, ???foo: foo};var bar = obj.foo; // function reference/alias!var a = "oops, global"; // `a` also property on global objectbar(); // "oops, global" obj.foo 
结果是:? foo() { ???console.log( this.a );}
bar      //变量bar的值就是函数foo, 因为bar被分配了obj.foo
结果是? foo() { ???console.log( this.a );}

所以: this指向全局对象window, this.a就是 window.a

另一个例子:参数传递

其实就是把obj.foo的值,分配给fn参数。等同于在doFoo函数内,声明了变量:var fn = obj.foo;

function foo() { ???console.log( this.a );}function doFoo(fn) { ???// `fn` is just another reference to `foo` ???fn(); // <-- call-site!}var obj = { ???a: 2, ???foo: foo};var a = "oops, global"; // `a` also property on global objectdoFoo( obj.foo ); // "oops, global"

看到了吧: 结果this绑定的是全局对象。this.a就是window.a

JavaScript内建函数也同样:

function foo() { ???console.log( this.a );}var obj = { ???a: 2, ???foo: foo};var a = "oops, global"; // `a` also property on global objectsetTimeout( obj.foo, 100 ); // "oops, global"setTimeout()函数相当于:function MySetTimeout(fn) { ???//0.1秒后; ???fn();}MySetTimeout( obj.foo )

函数回调丢失它们的this绑定是很常见的。

还有一类方式,是主动改变this:

Event handlers就会强制你的回调有一个this指向DOM中被激活的元素。

如果有一种方法可以固定住this,就好了!当然有了,见??,明确的绑定!

Explicit Binding

call()方法,apply()方法。第一个参数是一个对象的话,这个对象就绑定了this。

function foo() { ???console.log( this.a );}var obj = { ???a: 2};foo.call( obj ); // 2

??,call(..),apply(..)可接受多个参数,它们的用途这里不谈!

不幸的是,明确绑定,不能解决一个函数丢失它想要的this绑定的问题。

Hard Binding(explict and strong)

var bar = function() {foo.call( obj );};

API Call "Contexts"

new Binding


Everything In Order

Determining this


Binding Exceptions

Ignored this

Safer this

Indirection

Softening Binding


Lexical this


Review (TL;DR)

4条rule

小心:

箭头函数

You Don't Know JS: this & Object Prototypes( 第2章 this)

原文地址:https://www.cnblogs.com/chentianwei/p/9744504.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved