首頁  >  文章  >  web前端  >  JavaScript把new給拿捏住了

JavaScript把new給拿捏住了

WBOY
WBOY轉載
2022-04-08 19:12:392153瀏覽

本篇文章為大家帶來了關於javascript的相關知識,其中主要介紹了關於new的相關問題,new運算子創建一個用戶定義的物件類型的實例或具有建構函數的內建物件類型之一,希望對大家有幫助。

JavaScript把new給拿捏住了

【相關推薦:javascript影片教學

前言

什麼是new呢?

new運算子建立一個使用者定義的物件類型的實例或具有建構函數的內建物件類型之一。

光看定義還是有幾分晦澀,直接看一個具體的例子,來了解一下JavaScript中的new實現的功能。

舉例

// 现实中瘦不了,但网络中一定要保持苗条
function Thin_User(name, age) {
    this.name = name;
    this.age = age;
}

Thin_User.prototype.eatToMuch = function () {
    // 白日做梦吧,留下肥胖的泪水
    console.log('i eat so much, but i\'m very thin!!!');
}

Thin_User.prototype.isThin = true;

const xiaobao = new Thin_User('zcxiaobao', 18);
console.log(xiaobao.name);   // zcxiaobao
console.log(xiaobao.age);    // 18
console.log(xiaobao.isThin); // true
// i eat so much, but i'm very thin!!!
xiaobao.eatToMuch();

透過上面這個例子,我們可以發現xiaobao可以:

  • 訪問到建構子Thin_User中屬性
  • 訪問到Thin_User.prototype中屬性
##描述得更直白一點,

new 做了這些事:

    建立了一個空對象,物件的
  • __proto__->Thin_User.prototype
  • 執行建構函數,並將
  • this指向新物件
  • 傳回新物件

補充說明

因為

new#是關鍵字,我們無法像模擬陣列高階方法一樣覆蓋,因此我們寫一個函數createObject,來模擬

new

的效果。使用具體如下:
function Thin_User(name, age) {}

const u1 = new Thin_user(...)
const u2 = createObject(Thin_User, ...a\)

初步模擬

根據上面分析,

createObject
    所寫的大致步驟為:


#建立一個新物件
obj

設定obj.__proto__->constructor.prototype(

但JavaScript不建議直接修改__proto__屬性,提供了setPrototypeOf方法來專門修改原型

)使用

constructor.call/apply(obj, ...)

,將屬性加入obj

返回

obj

__proto__和prototype,可以看JavaScript之徹底理解原型與原型鏈

#call/apply,可以看JavaScript之手撕call、apply#學習完這些,我們就可以寫第一版程式碼:

function createObject(Con) {
    // 创建新对象obj
    // var obj = {};也可以
    var obj = Object.create(null);

    // 将obj.__proto__ -> 构造函数原型
    // (不推荐)obj.__proto__ = Con.prototype
    Object.setPrototypeOf(obj, Con.prototype);

    // 执行构造函数
    Con.apply(obj, [].slice.call(arguments, 1));

    // 返回新对象
    return obj;}
JavaScript把new給拿捏住了#傳回值效果

眾所周知,函數是有傳回值的,那麼建構子如果有回傳值,最後執行new後傳回的結果是怎樣的那?

傳回值為基本型別

假設建構子傳回值為一個基本型,我們來看看最後的回傳結果:

function Thin_User(name, age) {
    this.name = name;
    this.age = age;
    return 'i will keep thin forever';
}

Thin_User.prototype.eatToMuch = function () {
    console.log('i eat so much, but i\'m very thin!!!');
}

Thin_User.prototype.isThin = true;

const xiaobao = new Thin_User('zcxiaobao', 18);
console.log(xiaobao.name);   // zcxiaobao
console.log(xiaobao.age);    // 18
console.log(xiaobao.isThin); // true
// i eat so much, but i'm very thin!!!
xiaobao.eatToMuch();

最後的回傳結果好像受到任何干擾,難道構造函數不會對回傳值進行處理嗎?

不急,我們來接著測試一下傳回值為物件的情況。

返回值為物件######
function Thin_User(name, age) {
    this.name = name;
    this.age = age;
    return {
        name: name,
        age: age * 10,
        fat: true
    }
}

Thin_User.prototype.eatToMuch = function () {
    // 白日做梦吧,留下肥胖的泪水
    console.log('i eat so much, but i\'m very thin!!!');
}

Thin_User.prototype.isThin = true;

const xiaobao = new Thin_User('zcxiaobao', 18);
// Error: xiaobao.eatToMuch is not a function
xiaobao.eatToMuch();
###當我執行###eatToMuch###時,控制台直接報錯,沒有當前函數,於是我列印了## #xiaobao###物件:############發現###xiaobao###物件的###age###發生了改變,而且增加了###fat###屬性,剛好與建構函數的回傳值一樣。 ######看完這兩個例子,基本上可以理清建構函式有回傳值的情況:###當建構子回傳值為物件時,直接傳回這個物件。 #########終版模擬###
function createObject(Con) {
    // 创建新对象obj
    // var obj = {};也可以
    var obj = Object.create(null);

    // 将obj.__proto__ -> 构造函数原型
    // (不推荐)obj.__proto__ = Con.prototype
    Object.setPrototypeOf(obj, Con.prototype);

    // 执行构造函数,并接受构造函数返回值
    const ret = Con.apply(obj, [].slice.call(arguments, 1));

    // 若构造函数返回值为对象,直接返回该对象
    // 否则返回obj
    return typeof(ret) === 'object' ? ret: obj;}
###【相關推薦:###javascript影片教學###】####

以上是JavaScript把new給拿捏住了的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除