《你不知道的js》——this全面解析(代码片段)

qnlz的前端blog qnlz的前端blog     2022-11-22     268

关键词:

默认绑定

//全局对象用于默认绑定
function foo()
    console.log(this.a)

var a=2;
foo();  //2
//严格模式下,不能将全局对象用于默认绑定
function foo()
    ‘use strict‘;
    console.log(this.a)

var a=2;
foo();  //TypeError: this is undefined
//在严格模式下调用foo()则不影响默认绑定
function foo()
    console.log(this.a)

var a=2;
(function()
    ‘use strict‘;
    foo();
)();  //2

 

隐式绑定

//当函数拥有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象
function foo()
    console.log(this.a)

var obj=
    a:2,
    foo:foo

obj.foo();    //2
//对象属性链中只有上一层或者最后一层在调用位置中起作用
function foo()
    console.log(this.a)

var obj2=
    a:42,
    foo:foo

var obj1=
    a:2,
    obj2:obj2

obj1.obj2.foo();    //42
//this 被隐式绑定的函数会丢失绑定对象,也就是说会应用默认绑定,从而把this绑定到全局对象或者undefined上
function foo()
    console.log(this.a)

var obj=
    a:2,
    foo:foo
 
var bar=obj.foo;
var a="hello";
bar();  //hello
//参数传递其实就是隐式传递,因此我们传入函数是也会被隐式赋值
function foo()
    console.log(this.a)

function doFoo(fn)
    fn();

var obj=
    a:2,
    foo:foo


var bar=obj.foo;
var a="hello";
doFoo(obj.foo)  //hello
//回调函数丢失this绑定
function foo()
    console.log(this.a)

var obj=
    a:2,
    foo:foo
 
var a="hello";
setTimeout(obj.foo,100)   //hello

显式绑定

//通过foo.call(..),在调用foo时强制把它的this绑定到obj上
function foo()
    console.log(this.a)

var obj=
    a:2

foo.call(obj) //2
//硬绑定
function foo()
    console.log(this.a)

var obj=
    a:2
 
var bar=function()
    foo.call(obj)
;
bar(); //2
setTimeout(bar,100);  //2
//硬绑定的bar    不可能再修改它的this
bar.call(window); //2
//硬绑定典型应用场景:创建一个包裹函数,负责接收参数并返回值
function foo(something)
    console.log(this.a,something);
    return this.a + something;

var obj=
    a:2

var bar=function()
    return foo.apply(obj,arguments)

var b=bar(3);  //2 3
console.log(b)    //5
//硬绑定典型应用场景:创建一个可以重复使用的辅助函数
function foo(something)
    console.log(this.a,something);
    return this.a + something;

    //简单的辅助绑定函数
function bind(fn,obj)
    return function()
        return fn.apply(obj,arguments)
    

var obj=
    a:2

var bar=bind(foo,obj);
var b=bar(3); //2 3
console.log(b)  //5

 

《你不知道的js(中卷)》关于this(代码片段)

一、关于this:一)、为什么要用this?functionidentity() returnthis.name.toUpperCase();varme= name:"Kyle";varyou= name:"Reader";identity.call(me);//Kyleidentity.call(you);//Reader? 观察上面的代码,使 查看详情

你不知道的js系列上(45)-隐式混入(代码片段)

varSomething=  cool:function()    this.greeting=‘HelloWorld‘;    this.count=this.count?this.count+1:1;  Something.cool();Something.greeting;//‘HelloWorld‘Something.count;//1varAnother=  cool:func 查看详情

你不知道的js系列(19)-this调用位置(代码片段)

我们排除了一些对于this对错误理解并且明白了每个函数的this是在调用时被绑定的,完全取决于函数的调用位置。寻找调用位置就是寻找“函数被调用的位置”,但是做起来并没有这么简单,因为某些编程模式可能会隐藏... 查看详情

你不知道的js系列(23)-this绑定优先级(代码片段)

我们首先来看下隐式绑定和显示绑定哪个优先级更高functionfoo()  console.log(this.a)varobj1=  a:2,  foo:foovarobj2=  a:3,  foo:fooobj1.foo();//2obj2.foo();//3obj1.foo.call(obj2);//3obj2.foo.call(obj1);//2这个例子可以看到,显示绑定优先级比 查看详情

js你不知道的javascript笔记-this-四种绑定规则-绑定优先级-绑定例外-箭头函数(代码片段)

文章目录1.为什么要用`this`2.关于`this`的误解2.1`this`不是指向函数自身2.2`this`不指向函数的词法作用域3.什么是调用栈与调用位置4.`this`的绑定规则4.1默认绑定`fun()`4.2隐式绑定`obj.fun()`隐... 查看详情

你不知道的js(代码片段)

1、作用域 块级作用域let只在函数内部自己的作用域内有效 全局作用域var 函数作用域 找不到作用域抛出ReferenceError变量有了则抛出TypeError 先声明后赋值 函数提升变量提升函数优先,函数声明提升在普通变量之前 函数表达... 查看详情

js中你不知道的一些概念知识(代码片段)

DOM元素e的e.getAttribute(propName)和e.propName有什么区别和联系e.getAttribute(),是标准DOM操作文档元素属性的方法,具有通用性可在任意文档上使用,返回元素在源文件中设置的属性e.propName通常是在HTML文档中访问特定元素的... 查看详情

你不知道的js系列-引擎怎么查找变量(代码片段)

对代码进行处理的三个角色引擎:从头到尾负责整个JavaScript程序的编译和执行过程编译器:负责语法分析及代码生成等作用域:负责收集并维护所有变量的查询 vara=2;编译器首先会将这段程序分解成词法单元,然后将词法单... 查看详情

this全面解析--javascript中的

上一章我们排除了一些对this的错误认识和知道了this是在调用函数时被绑定的,完全取决于函数的调用位置。先介绍两个概念:调用位置和调用栈。调用栈:就是为了到达当前执行位置所调用的所有函数。调用位置:在当前正在... 查看详情

《你不知道的js(中卷)》对象(代码片段)

三、对象:一)、语法:对象有两种形式定义:声明(文字)形式:varmyObj=key:value//...;构造形式:varmyObj=newObject();myObj.key=value;在声明形式中可以添加多个键/值对,但是在构造形式中必须逐个添加属性。1、类型:? 对象是JS的基... 查看详情

你不知道的js-行为委托

1、面向委托的设计2、委托理论Task={setID:function(ID){this.id=ID;},outputID:function(){console.log(this.id)};};//让XYZ委托TaskXYZ=object.create(Task);XYZ.prepareTask=function(ID,Label){this.setID(ID);this.label=Label; 查看详情

flv.js全面解析(代码片段)

Flv.js全面解析常见直播协议Flv.js概览Flv.js结构图架构图功能API文档相关MediaDataSource的字段列表如下,Configflvjs.getFeatureList()Flv.js兼容性直播服务器搭建推流ffmpeg推流OBS推流flv.js搭建过程下载链接flv.jsDemo演示播放器主要参数源... 查看详情

你不知道的js系列(33)-对象复制(代码片段)

JS初学者最常见的问题之一就是如何复制一个对象。看起来应该有一个内置的copy()方法,实际上比想象中的更复杂,我们无法选择一个默认的复制算法functionanotherFunction()/**...*/;varanotherObject=c:true;varanotherArray=[];varmyObject=  a:2, ... 查看详情

《你不知道的js》提升(代码片段)

四、提升:一)、声明与赋值:? 在JS引擎中,我们一般认为的变量或函数声明,实际上分为两个部分。声明赋值//变量提升a=2;vara;console.log(a);//函数提升foo();functionfoo() console.log(1);? vara=2;? 这句声明实际上会被看为vara;a=2;两个部分... 查看详情

你不知道的js(代码片段)

作用域LHSRHS区别如果RHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出ReferenceError异常。值得注意的是,ReferenceError是非常重要的异常类型。相较之下,当引擎执行LHS查询时,如果在顶层(全局作用域)中也无法找到目标... 查看详情

读书笔记《你不知道的javascript(上卷)》——第二部分this和对象原型(代码片段)

文章目录第6章行为委托6.1面向委托的设计6.1.1类理论6.1.2委托理论1.互相委托(禁止)2.调试6.1.3比较思维模型6.2类与对象6.2.1控件“类”ES6的class语法糖6.2.2委托控件对象6.3更简洁的设计反类6.4更好的语法反词法6... 查看详情

你不知道的js系列(39)-对象遍历(代码片段)

for循环可以遍历数组varmyArray=[1,2,3];for(vari=0;i<myArray.length;i++)  console.log(myArray[i])//123ES5增加了数组的辅助迭代器,包括forEach(...)、every(...)、some(...)forEach(...)会遍历数组中的所有值并忽略回调函数的返回值every(...)会一直运行直... 查看详情

《你不知道的js(上卷)》作用域闭包(代码片段)

五、作用域闭包:? 闭包不是神奇的魔法,它只是遵循我们前几章一直介绍的词法作用域书写代码的自然结果。? 闭包是由函数以及声明该函数的词法环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。一... 查看详情