国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【進(jìn)階3-4期】深度解析bind原理、使用場景及模擬實(shí)現(xiàn)

guyan0319 / 1916人閱讀

摘要:返回的綁定函數(shù)也能使用操作符創(chuàng)建對象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器,提供的值被忽略,同時調(diào)用時的參數(shù)被提供給模擬函數(shù)。

bind()
bind() 方法會創(chuàng)建一個新函數(shù),當(dāng)這個新函數(shù)被調(diào)用時,它的 this 值是傳遞給 bind() 的第一個參數(shù),傳入bind方法的第二個以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。bind返回的綁定函數(shù)也能使用 new 操作符創(chuàng)建對象:這種行為就像把原函數(shù)當(dāng)成構(gòu)造器,提供的 this 值被忽略,同時調(diào)用時的參數(shù)被提供給模擬函數(shù)。(來自參考1)

語法:fun.bind(thisArg[, arg1[, arg2[, ...]]])

bind 方法與 call / apply 最大的不同就是前者返回一個綁定上下文的函數(shù),而后兩者是直接執(zhí)行了函數(shù)。

來個例子說明下

var value = 2;

var foo = {
    value: 1
};

function bar(name, age) {
    return {
        value: this.value,
        name: name,
        age: age
    }
};

bar.call(foo, "Jack", 20); // 直接執(zhí)行了函數(shù)
// {value: 1, name: "Jack", age: 20}

var bindFoo1 = bar.bind(foo, "Jack", 20); // 返回一個函數(shù)
bindFoo1();
// {value: 1, name: "Jack", age: 20}

var bindFoo2 = bar.bind(foo, "Jack"); // 返回一個函數(shù)
bindFoo2(20);
// {value: 1, name: "Jack", age: 20}

通過上述代碼可以看出bind 有如下特性:

1、可以指定this

2、返回一個函數(shù)

3、可以傳入?yún)?shù)

4、柯里化

使用場景
1、業(yè)務(wù)場景

經(jīng)常有如下的業(yè)務(wù)場景

var nickname = "Kitty";
function Person(name){
    this.nickname = name;
    this.distractedGreeting = function() {

        setTimeout(function(){
            console.log("Hello, my name is " + this.nickname);
        }, 500);
    }
}
 
var person = new Person("jawil");
person.distractedGreeting();
//Hello, my name is Kitty

這里輸出的nickname是全局的,并不是我們創(chuàng)建 person 時傳入的參數(shù),因?yàn)?setTimeout 在全局環(huán)境中執(zhí)行(不理解的查看【進(jìn)階3-1期】),所以 this 指向的是window

這邊把 setTimeout 換成異步回調(diào)也是一樣的,比如接口請求回調(diào)。

解決方案有下面兩種。

解決方案1:緩存 this

var nickname = "Kitty";
function Person(name){
    this.nickname = name;
    this.distractedGreeting = function() {
        
        var self = this; // added
        setTimeout(function(){
            console.log("Hello, my name is " + self.nickname); // changed
        }, 500);
    }
}
 
var person = new Person("jawil");
person.distractedGreeting();
// Hello, my name is jawil

解決方案2:使用 bind

var nickname = "Kitty";
function Person(name){
    this.nickname = name;
    this.distractedGreeting = function() {

        setTimeout(function(){
            console.log("Hello, my name is " + this.nickname);
        }.bind(this), 500);
    }
}
 
var person = new Person("jawil");
person.distractedGreeting();
// Hello, my name is jawil

完美!

2、驗(yàn)證是否是數(shù)組

【進(jìn)階3-3期】介紹了 call 的使用場景,這里重新回顧下。

function isArray(obj){ 
    return Object.prototype.toString.call(obj) === "[object Array]";
}
isArray([1, 2, 3]);
// true

// 直接使用 toString()
[1, 2, 3].toString();     // "1,2,3"
"123".toString();         // "123"
123.toString();         // SyntaxError: Invalid or unexpected token
Number(123).toString(); // "123"
Object(123).toString(); // "123"

可以通過toString() 來獲取每個對象的類型,但是不同對象的 toString()有不同的實(shí)現(xiàn),所以通過 Object.prototype.toString() 來檢測,需要以 call() / apply() 的形式來調(diào)用,傳遞要檢查的對象作為第一個參數(shù)。

另一個驗(yàn)證是否是數(shù)組的方法,這個方案的優(yōu)點(diǎn)是可以直接使用改造后的 toStr

var toStr = Function.prototype.call.bind(Object.prototype.toString);
function isArray(obj){ 
    return toStr(obj) === "[object Array]";
}
isArray([1, 2, 3]);
// true

// 使用改造后的 toStr
toStr([1, 2, 3]);     // "[object Array]"
toStr("123");         // "[object String]"
toStr(123);         // "[object Number]"
toStr(Object(123)); // "[object Number]"

上面方法首先使用 Function.prototype.call函數(shù)指定一個 this 值,然后 .bind 返回一個新的函數(shù),始終將 Object.prototype.toString 設(shè)置為傳入?yún)?shù)。其實(shí)等價于 Object.prototype.toString.call()

這里有一個前提toString()方法沒有被覆蓋

Object.prototype.toString = function() {
    return "";
}
isArray([1, 2, 3]);
// false
3、柯里化(curry)
只傳遞給函數(shù)一部分參數(shù)來調(diào)用它,讓它返回一個函數(shù)去處理剩下的參數(shù)。

可以一次性地調(diào)用柯里化函數(shù),也可以每次只傳一個參數(shù)分多次調(diào)用。

var add = function(x) {
  return function(y) {
    return x + y;
  };
};

var increment = add(1);
var addTen = add(10);

increment(2);
// 3

addTen(2);
// 12

add(1)(2);
// 3

這里定義了一個 add 函數(shù),它接受一個參數(shù)并返回一個新的函數(shù)。調(diào)用 add 之后,返回的函數(shù)就通過閉包的方式記住了 add 的第一個參數(shù)。所以說 bind 本身也是閉包的一種使用場景。

模擬實(shí)現(xiàn)

bind() 函數(shù)在 ES5 才被加入,所以并不是所有瀏覽器都支持,IE8及以下的版本中不被支持,如果需要兼容可以使用 Polyfill 來實(shí)現(xiàn)。

首先我們來實(shí)現(xiàn)以下四點(diǎn)特性:

1、可以指定this

2、返回一個函數(shù)

3、可以傳入?yún)?shù)

4、柯里化

模擬實(shí)現(xiàn)第一步

對于第 1 點(diǎn),使用 call / apply 指定 this

對于第 2 點(diǎn),使用 return 返回一個函數(shù)。

結(jié)合前面 2 點(diǎn),可以寫出第一版,代碼如下:

// 第一版
Function.prototype.bind2 = function(context) {
    var self = this; // this 指向調(diào)用者
    return function () { // 實(shí)現(xiàn)第 2點(diǎn)
        return self.apply(context); // 實(shí)現(xiàn)第 1 點(diǎn)
    }
}

測試一下

// 測試用例
var value = 2;
var foo = {
    value: 1
};

function bar() {
    return this.value;
}

var bindFoo = bar.bind2(foo);

bindFoo(); // 1
模擬實(shí)現(xiàn)第二步

對于第 3 點(diǎn),使用 arguments 獲取參數(shù)數(shù)組并作為 self.apply() 的第二個參數(shù)。

對于第 4 點(diǎn),獲取返回函數(shù)的參數(shù),然后同第3點(diǎn)的參數(shù)合并成一個參數(shù)數(shù)組,并作為 self.apply() 的第二個參數(shù)。

// 第二版
Function.prototype.bind2 = function (context) {

    var self = this;
    // 實(shí)現(xiàn)第3點(diǎn),因?yàn)榈?個參數(shù)是指定的this,所以只截取第1個之后的參數(shù)
    // arr.slice(begin); 即 [begin, end]
    var args = Array.prototype.slice.call(arguments, 1); 

    return function () {
        // 實(shí)現(xiàn)第4點(diǎn),這時的arguments是指bind返回的函數(shù)傳入的參數(shù)
        // 即 return function 的參數(shù)
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply( context, args.concat(bindArgs) );
    }
}

測試一下:

// 測試用例
var value = 2;

var foo = {
    value: 1
};

function bar(name, age) {
    return {
        value: this.value,
        name: name,
        age: age
    }
};

var bindFoo = bar.bind2(foo, "Jack");
bindFoo(20);
// {value: 1, name: "Jack", age: 20}
模擬實(shí)現(xiàn)第三步

到現(xiàn)在已經(jīng)完成大部分了,但是還有一個難點(diǎn),bind 有以下一個特性

一個綁定函數(shù)也能使用new操作符創(chuàng)建對象:這種行為就像把原函數(shù)當(dāng)成構(gòu)造器,提供的 this 值被忽略,同時調(diào)用時的參數(shù)被提供給模擬函數(shù)。

來個例子說明下:

var value = 2;
var foo = {
    value: 1
};
function bar(name, age) {
    this.habit = "shopping";
    console.log(this.value);
    console.log(name);
    console.log(age);
}
bar.prototype.friend = "kevin";

var bindFoo = bar.bind(foo, "Jack");
var obj = new bindFoo(20);
// undefined
// Jack
// 20

obj.habit;
// shopping

obj.friend;
// kevin

上面例子中,運(yùn)行結(jié)果this.value 輸出為 undefined,這不是全局value 也不是foo對象中的value,這說明 bindthis 對象失效了,new 的實(shí)現(xiàn)中生成一個新的對象,這個時候的 this指向的是 obj。(【進(jìn)階3-1期】有介紹new的實(shí)現(xiàn)原理,下一期也會重點(diǎn)介紹)

這里可以通過修改返回函數(shù)的原型來實(shí)現(xiàn),代碼如下:

// 第三版
Function.prototype.bind2 = function (context) {
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);

    var fBound = function () {
        var bindArgs = Array.prototype.slice.call(arguments);
        
        // 注釋1
        return self.apply(
            this instanceof fBound ? this : context, 
            args.concat(bindArgs)
        );
    }
    // 注釋2
    fBound.prototype = this.prototype;
    return fBound;
}

注釋1:

當(dāng)作為構(gòu)造函數(shù)時,this 指向?qū)嵗藭r this instanceof fBound 結(jié)果為 true,可以讓實(shí)例獲得來自綁定函數(shù)的值,即上例中實(shí)例會具有 habit 屬性。

當(dāng)作為普通函數(shù)時,this 指向 window,此時結(jié)果為 false,將綁定函數(shù)的 this 指向 context

注釋2: 修改返回函數(shù)的 prototype 為綁定函數(shù)的 prototype,實(shí)例就可以繼承綁定函數(shù)的原型中的值,即上例中 obj 可以獲取到 bar 原型上的 friend

注意:這邊涉及到了原型、原型鏈和繼承的知識點(diǎn),可以看下我之前的文章。

JavaScript常用八種繼承方案

模擬實(shí)現(xiàn)第四步

上面實(shí)現(xiàn)中 fBound.prototype = this.prototype有一個缺點(diǎn),直接修改 fBound.prototype 的時候,也會直接修改 this.prototype

來個代碼測試下:

// 測試用例
var value = 2;
var foo = {
    value: 1
};
function bar(name, age) {
    this.habit = "shopping";
    console.log(this.value);
    console.log(name);
    console.log(age);
}
bar.prototype.friend = "kevin";

var bindFoo = bar.bind2(foo, "Jack"); // bind2
var obj = new bindFoo(20); // 返回正確
// undefined
// Jack
// 20

obj.habit; // 返回正確
// shopping

obj.friend; // 返回正確
// kevin

obj.__proto__.friend = "Kitty"; // 修改原型

bar.prototype.friend; // 返回錯誤,這里被修改了
// Kitty

解決方案是用一個空對象作為中介,把 fBound.prototype 賦值為空對象的實(shí)例(原型式繼承)。

var fNOP = function () {};            // 創(chuàng)建一個空對象
fNOP.prototype = this.prototype;     // 空對象的原型指向綁定函數(shù)的原型
fBound.prototype = new fNOP();        // 空對象的實(shí)例賦值給 fBound.prototype

這邊可以直接使用ES5的 Object.create()方法生成一個新對象

fBound.prototype = Object.create(this.prototype);

不過 bindObject.create()都是ES5方法,部分IE瀏覽器(IE < 9)并不支持,Polyfill中不能用 Object.create()實(shí)現(xiàn) bind,不過原理是一樣的。

第四版目前OK啦,代碼如下:

// 第四版,已通過測試用例
Function.prototype.bind2 = function (context) {

    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);

    var fNOP = function () {};

    var fBound = function () {
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(
            this instanceof fNOP ? this : context, 
            args.concat(bindArgs)
        );
    }

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
}
模擬實(shí)現(xiàn)第五步

到這里其實(shí)已經(jīng)差不多了,但有一個問題是調(diào)用 bind 的不是函數(shù),這時候需要拋出異常。

if (typeof this !== "function") {
  throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}

所以完整版模擬實(shí)現(xiàn)代碼如下:

// 第五版
Function.prototype.bind2 = function (context) {

    if (typeof this !== "function") {
      throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);

    var fNOP = function () {};

    var fBound = function () {
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
    }

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
}
【進(jìn)階3-2期】思考題解
// 1、賦值語句是右執(zhí)行的,此時會先執(zhí)行右側(cè)的對象
var obj = {
    // 2、say 是立即執(zhí)行函數(shù)
    say: function() {
        function _say() {
            // 5、輸出 window
            console.log(this);
        }
        // 3、編譯階段 obj 賦值為 undefined
        console.log(obj);
        // 4、obj是 undefined,bind 本身是 call實(shí)現(xiàn),
        // 【進(jìn)階3-3期】:call 接收 undefined 會綁定到 window。
        return _say.bind(obj);
    }(),
};
obj.say();
【進(jìn)階3-3期】思考題解

call 的模擬實(shí)現(xiàn)如下,那有沒有什么問題呢?

Function.prototype.call = function (context) {
    context = context || window;
    context.fn = this;

    var args = [];
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push("arguments[" + i + "]");
    }
    var result = eval("context.fn(" + args +")");

    delete context.fn;
    return result;
}

當(dāng)然是有問題的,其實(shí)這里假設(shè) context 對象本身沒有 fn 屬性,這樣肯定不行,我們必須保證 fn屬性的唯一性。

ES3下模擬實(shí)現(xiàn)

解決方法也很簡單,首先判斷 context中是否存在屬性 fn,如果存在那就隨機(jī)生成一個屬性fnxx,然后循環(huán)查詢 context 對象中是否存在屬性 fnxx。如果不存在則返回最終值。

一種循環(huán)方案實(shí)現(xiàn)代碼如下:

function fnFactory(context) {
    var unique_fn = "fn";
    while (context.hasOwnProperty(unique_fn)) {
        unique_fn = "fn" + Math.random(); // 循環(huán)判斷并重新賦值
    }
    
    return unique_fn;
}

一種遞歸方案實(shí)現(xiàn)代碼如下:

function fnFactory(context) {
    var unique_fn = "fn" + Math.random();
    if(context.hasOwnProperty(unique_fn)) {
        // return arguments.callee(context); ES5 開始禁止使用
        return fnFactory(context); // 必須 return
    } else {
        return unique_fn;
    }
}

模擬實(shí)現(xiàn)完整代碼如下:

function fnFactory(context) {
    var unique_fn = "fn";
    while (context.hasOwnProperty(unique_fn)) {
        unique_fn = "fn" + Math.random(); // 循環(huán)判斷并重新賦值
    }
    
    return unique_fn;
}

Function.prototype.call = function (context) {
    context = context || window;
    var fn = fnFactory(context); // added
    context[fn] = this; // changed

    var args = [];
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push("arguments[" + i + "]");
    }
    var result = eval("context[fn](" + args +")"); // changed

    delete context[fn]; // changed
    return result;
}

// 測試用例在下面
ES6下模擬實(shí)現(xiàn)

ES6有一個新的基本類型Symbol,表示獨(dú)一無二的值,用法如下。

const symbol1 = Symbol();
const symbol2 = Symbol(42);
const symbol3 = Symbol("foo");

console.log(typeof symbol1); // "symbol"
console.log(symbol3.toString()); // "Symbol(foo)"
console.log(Symbol("foo") === Symbol("foo")); // false

不能使用 new 命令,因?yàn)檫@是基本類型的值,不然會報錯。

new Symbol();
// TypeError: Symbol is not a constructor

模擬實(shí)現(xiàn)完整代碼如下:

Function.prototype.call = function (context) {
  context = context || window;
  var fn = Symbol(); // added
  context[fn] = this; // changed

  let args = [...arguments].slice(1);
  let result = context[fn](...args); // changed

  delete context[fn]; // changed
  return result;
}
// 測試用例在下面

測試用例在這里:

// 測試用例
var value = 2;
var obj = {
    value: 1,
    fn: 123
}

function bar(name, age) {
    console.log(this.value);
    return {
        value: this.value,
        name: name,
        age: age
    }
}

bar.call(null); 
// 2

console.log(bar.call(obj, "kevin", 18));
// 1
// {value: 1, name: "kevin", age: 18}

console.log(obj);
// {value: 1, fn: 123}
擴(kuò)展一下

有兩種方案可以判斷對象中是否存在某個屬性。

var obj = {
     a: 2
};
Object.prototype.b = function() {
    return "hello b";
}

1、in 操作符

in 操作符會檢查屬性是否存在對象及其 [[Prototype]] 原型鏈中。

("a" in obj);     // true
("b" in obj);     // true

2、Object.hasOwnProperty(...)方法

hasOwnProperty(...)只會檢查屬性是否存在對象中,不會向上檢查其原型鏈。

obj.hasOwnProperty("a");     //true
obj.hasOwnProperty("b");     //false

注意以下幾點(diǎn):

1、看起來 in 操作符可以檢查容器內(nèi)是否有某個值,實(shí)際上檢查的是某個屬性名是否存在。對于數(shù)組來說,4 in [2, 4, 6] 結(jié)果返回 false,因?yàn)?[2, 4, 6] 這個數(shù)組中包含的屬性名是0,1,2 ,沒有4

2、所有普通對象都可以通過 Object.prototype 的委托來訪問 hasOwnProperty(...),但是對于一些特殊對象( Object.create(null) 創(chuàng)建)沒有連接到 Object.prototype,這種情況必須使用 Object.prototype.hasOwnProperty.call(obj, "a"),顯示綁定到 obj 上。又是一個 call 的用法

本期思考題

用 JS 實(shí)現(xiàn)一個無限累加的函數(shù) add,示例如下:

add(1); // 1
add(1)(2);  // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10 

// 以此類推
參考
不用 call 和 apply 方法模擬實(shí)現(xiàn) ES5 的 bind 方法

JavaScript 深入之 bind 的模擬實(shí)現(xiàn)

MDN 之 Function.prototype.bind()

MDN 之 Symbol

第 4 章: 柯里化(curry)

進(jìn)階系列目錄

【進(jìn)階1期】 調(diào)用堆棧

【進(jìn)階2期】 作用域閉包

【進(jìn)階3期】 this全面解析

【進(jìn)階4期】 深淺拷貝原理

【進(jìn)階5期】 原型Prototype

【進(jìn)階6期】 高階函數(shù)

【進(jìn)階7期】 事件機(jī)制

【進(jìn)階8期】 Event Loop原理

【進(jìn)階9期】 Promise原理

【進(jìn)階10期】Async/Await原理

【進(jìn)階11期】防抖/節(jié)流原理

【進(jìn)階12期】模塊化詳解

【進(jìn)階13期】ES6重難點(diǎn)

【進(jìn)階14期】計算機(jī)網(wǎng)絡(luò)概述

【進(jìn)階15期】瀏覽器渲染原理

【進(jìn)階16期】webpack配置

【進(jìn)階17期】webpack原理

【進(jìn)階18期】前端監(jiān)控

【進(jìn)階19期】跨域和安全

【進(jìn)階20期】性能優(yōu)化

【進(jìn)階21期】VirtualDom原理

【進(jìn)階22期】Diff算法

【進(jìn)階23期】MVVM雙向綁定

【進(jìn)階24期】Vuex原理

【進(jìn)階25期】Redux原理

【進(jìn)階26期】路由原理

【進(jìn)階27期】VueRouter源碼解析

【進(jìn)階28期】ReactRouter源碼解析

交流

進(jìn)階系列文章匯總?cè)缦拢瑑?nèi)有優(yōu)質(zhì)前端資料,覺得不錯點(diǎn)個star。

https://github.com/yygmind/blog

我是木易楊,網(wǎng)易高級前端工程師,跟著我每周重點(diǎn)攻克一個前端面試重難點(diǎn)。接下來讓我?guī)阕哌M(jìn)高級前端的世界,在進(jìn)階的路上,共勉!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/100736.html

相關(guān)文章

  • 進(jìn)階3-3深度解析 call 和 apply 原理使用場景實(shí)現(xiàn)

    摘要:之前文章詳細(xì)介紹了的使用,不了解的查看進(jìn)階期。不同的引擎有不同的限制,核心限制在,有些引擎會拋出異常,有些不拋出異常但丟失多余參數(shù)。存儲的對象能動態(tài)增多和減少,并且可以存儲任何值。這邊采用方法來實(shí)現(xiàn),拼成一個函數(shù)。 之前文章詳細(xì)介紹了 this 的使用,不了解的查看【進(jìn)階3-1期】。 call() 和 apply() call() 方法調(diào)用一個函數(shù), 其具有一個指定的 this 值和分...

    godlong_X 評論0 收藏0
  • 進(jìn)階3-5深度解析 new 原理模擬實(shí)現(xiàn)

    摘要:使用指定的參數(shù)調(diào)用構(gòu)造函數(shù),并將綁定到新創(chuàng)建的對象。由構(gòu)造函數(shù)返回的對象就是表達(dá)式的結(jié)果。情況返回以外的基本類型實(shí)例中只能訪問到構(gòu)造函數(shù)中的屬性,和情況完全相反,結(jié)果相當(dāng)于沒有返回值。 定義 new 運(yùn)算符創(chuàng)建一個用戶定義的對象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對象的實(shí)例。 ——(來自于MDN) 舉個栗子 function Car(color) { this.color = co...

    Baaaan 評論0 收藏0
  • 進(jìn)階 6-2 】深入高階函數(shù)應(yīng)用之柯里化

    摘要:引言上一節(jié)介紹了高階函數(shù)的定義,并結(jié)合實(shí)例說明了使用高階函數(shù)和不使用高階函數(shù)的情況。我們期望函數(shù)輸出,但是實(shí)際上調(diào)用柯里化函數(shù)時,所以調(diào)用時就已經(jīng)執(zhí)行并輸出了,而不是理想中的返回閉包函數(shù),所以后續(xù)調(diào)用將會報錯。引言 上一節(jié)介紹了高階函數(shù)的定義,并結(jié)合實(shí)例說明了使用高階函數(shù)和不使用高階函數(shù)的情況。后面幾部分將結(jié)合實(shí)際應(yīng)用場景介紹高階函數(shù)的應(yīng)用,本節(jié)先來聊聊函數(shù)柯里化,通過介紹其定義、比較常見的...

    stackvoid 評論0 收藏0
  • 進(jìn)階4-2】Object.assign 原理實(shí)現(xiàn)

    摘要:木易楊注意原始類型被包裝為對象木易楊原始類型會被包裝,和會被忽略。木易楊原因在于時,其屬性描述符為不可寫,即。木易楊解決方法也很簡單,使用我們在進(jìn)階期中介紹的就可以了,使用如下。 引言 上篇文章介紹了賦值、淺拷貝和深拷貝,其中介紹了很多賦值和淺拷貝的相關(guān)知識以及兩者區(qū)別,限于篇幅只介紹了一種常用深拷貝方案。 本篇文章會先介紹淺拷貝 Object.assign 的實(shí)現(xiàn)原理,然后帶你手動實(shí)...

    layman 評論0 收藏0
  • 進(jìn)階3-2】JavaScript深入之重新認(rèn)識箭頭函數(shù)的this

    摘要:箭頭函數(shù)的尋值行為與普通變量相同,在作用域中逐級尋找。題目這次通過構(gòu)造函數(shù)來創(chuàng)建一個對象,并執(zhí)行相同的個方法。 我們知道this綁定規(guī)則一共有5種情況: 1、默認(rèn)綁定(嚴(yán)格/非嚴(yán)格模式) 2、隱式綁定 3、顯式綁定 4、new綁定 5、箭頭函數(shù)綁定 其實(shí)大部分情況下可以用一句話來概括,this總是指向調(diào)用該函數(shù)的對象。 但是對于箭頭函數(shù)并不是這樣,是根據(jù)外層(函數(shù)或者全局)作用域(...

    Rainie 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<