精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
深入理解new運算符

在 JavaScript 中,new 運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象的實例。創建一個對象很簡單,為什么我們還要多此一舉使用 new 運算符呢?它到底有什么樣的魔力?

認識 new 運算符

通過下面的例子理解 new 運算符:

function Person (name) {
  this.name = name
}

Person.prototype.getName = function () {
  console.log(this.name)
}

var joe = new Person('joe')

joe.sayHello = function () {
  console.log('Hello!')
}

joe.getName() // joe
joe.sayHello() // Hello!

Person.sayHello() // Uncaught TypeError: Person.sayHello is not a function

Person 是一個普通的函數,當它與 new 運算符一起使用時,Person 就是一個構造函數。通過 new Person('joe') 得到的新對象 joe 繼承了 Person 的屬性,同時,this 也指向 joe 實例。為 joe 添加的屬性 sayHello 不會影響 Person,即 joe 是區別與 Person 的一個新對象。

因此,通過 new 創建的實例對象和構造函數之間建立了一條原型鏈,并通過原型鏈賦予實例對象繼承屬性的能力。

new 的原理和實現

通過上面的分析,new 運算符內部做了如下四個操作:

  • 創建一個空的簡單 JavaScript 對象(即{});
  • 鏈接新對象(即設置該新對象的構造函數)到函數對象;
  • 將新創建的對象作為 this 的上下文;
  • 如果該函數沒有返回對象,返回新創建的對象。

new 的實現如下:

function newOperator (ctor, ...args) {
  var obj = {};
  obj.__proto__ = ctor.prototype
  var res = ctor.apply(obj, args)
  return res || obj;
}

優化一下代碼:

function newOperator (ctor, ...args) {
  var o = Object.create(ctor.prototype) // 合并第一和第二步:創建一個空的簡單 JavaScript 對象(即{}),鏈接新對象(即設置該新對象的構造函數)到函數對象
  return fn.apply(o, args) || o
}

使用 newOperator 函數測試上面 Person 的例子:

function Person(name) {
  this.name = name
}

Person.prototype.getName = function () {
  console.log(this.name)
}

var joe = newOperator(Person, 'joe')

joe.sayHello = function () {
  console.log('Hello!')
}

joe.getName() // joe
joe.sayHello() // Hello!

Person.sayHello() // Uncaught TypeError: Person.sayHello is not a function

結果是一致的。

更好的檢查方式是:

function Person(name) {
  this.name = name
}

console.log(new Person('joe')) // @1
console.log(newOperator(Person, 'joe')) // @2

@1 和 @2 在控制臺的顯示信息是一模一樣的。

判斷是否使用 new 關鍵字

在 JavaScript 中,一個實例對象的創建必須使用 new 關鍵字。但是限于 JavaScript 的語法特征,實際上構造函數同樣可以像普通函數那樣直接執行。那么構造函數內部如何判斷是否使用了 new 關鍵字?

使用 instanceof 檢測

通過理解 new 操作符的原理,可知,在執行 new 操作時,構造函數的 prototype 賦值給了實例的 proto 屬性。在 JavaScript 中 instanceof 可以用來檢測對象的原型鏈,如:a instanceof A 用來檢測 a 是否是 A 的實例(即 a 的原型鏈中存在原型對象 A)。

function Person () {
  if (this instanceof Person) {
    console.log('new 調用')
  } else {
    console.log('普通函數調用')
  }
}

const foo = new Person() // new 調用
const bar = Person()     // 普通函數調用

使用 new.target 屬性

在 ES6 中引入了 new.target 屬性,new.target 屬性允許你檢測函數或構造方法是否是通過 new 運算符被調用的。在通過 new 運算符被初始化的函數或構造方法中,new.target 返回一個指向構造方法或函數的引用。在普通的函數調用中,new.target 的值是 undefined。

function Person () {
  console.log(new.target)
}

const foo = new Person() // ? Person () { console.log(new.target) }
const bar = Person()     // undefined
本站僅提供存儲服務,所有內容均由用戶發布,如發現有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JS 對象封裝的常用方式
JavaScript 面向對象編程思想簡介
詳解 JavaScript 中的 this
悟透JavaScript(續)
圖靈社區 : 閱讀 : 面向對象JavaScript入門——來自Mozilla的官網教程
Java程序員從笨鳥到菜鳥之(二十九)javascript對象的創建和繼承實現
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服

主站蜘蛛池模板: 桦南县| 滕州市| 平顶山市| 天柱县| 南江县| 大悟县| 东海县| 静海县| 师宗县| 桑植县| 敖汉旗| 洛扎县| 许昌市| 河间市| 平远县| 卓资县| 井研县| 罗城| 阿荣旗| 临湘市| 视频| 柳州市| 于田县| 尉氏县| 林芝县| 滁州市| 牟定县| 保德县| 定安县| 苗栗市| 虞城县| 元阳县| 长白| 诸暨市| 海南省| 平塘县| 抚顺市| 石门县| 泸溪县| 延安市| 贵阳市|