首頁 > web前端 > js教程 > 主體

JavaScript 建構函式和 'new' 運算子詳解

coldplay.xixi
發布: 2020-11-13 17:39:52
轉載
2553 人瀏覽過

javascript欄位介紹 "new" 運算子。

JavaScript 建構函式和 'new' 運算子詳解

建構器和運算子 "new"

常規的 {...} 語法允許建立一個物件。但是我們經常需要建立許多類似的對象,例如多個使用者或選單項目等。

這可以使用建構函式和 "new" 運算子來實作。

建構子

建構子在技術上是常規函數。不過有兩個約定:

  1. 它們的命名以大寫字母開頭。
  2. 它們只能由 "new" 運算子來執行。

例如:

function User(name) {  this.name = name;  this.isAdmin = false;
}let user = new User("Jack");

alert(user.name); // Jackalert(user.isAdmin); // false复制代码
登入後複製

當一個函數被使用new# 運算子執行時,它會依照下列步驟:

  1. 一個新的空物件被創建並指派給this
  2. 函數體執行。通常它會修改 this,為其新增新的屬性。
  3. 傳回 this 的值。

換句話說,new User(...) 做的就是類似的事情:

function User(name) {  // this = {};(隐式创建)

  // 添加属性到 this
  this.name = name;  this.isAdmin = false;  // return this;(隐式返回)}复制代码
登入後複製

所以new User("Jack" ) 的結果是相同的物件:

let user = {  name: "Jack",  isAdmin: false};复制代码
登入後複製

現在,如果我們想要建立其他用戶,我們可以呼叫new User("Ann")new User( "Alice") 等。比每次都使用字面量創建要短得多,而且更易於閱讀。

這是建構器的主要目的 —— 實作可重複使用的物件建立程式碼。

讓我們再強調一次 —— 從技術上講,任何函數都可以用作建構器。即:任何函數都可以透過 new 來運行,它會執行上面的演算法。 「首字母大寫」是一個共同的約定,以明確表示一個函數將被使用 new 來運行。

new function() { ... }

如果我們有許多行用於建立單一複雜物件的程式碼,我們可以將它們封裝在建構函式中,像這樣:

let user = new function() {  this.name = "John";  this.isAdmin = false;  // ……用于用户创建的其他代码
  // 也许是复杂的逻辑和语句
  // 局部变量等};复制代码
登入後複製

建構器不能再次調用,因為它不保存在任何地方,只是被創建和調用。因此,這個技巧旨在封裝建立單一物件的程式碼,而無需將來重複使用。

建構器模式測試:new.target

進階內容:

本節涉及的語法內容很少使用,除非你想了解所有內容,否則你可以直接跳過該語法。

在一個函數內部,我們可以使用 new.target 屬性來檢查它是否被使用 new 進行呼叫了。

對於常規調用,它為空,對於使用new 的調用,則等於該函數:

function User() {
  alert(new.target);
}// 不带 "new":User(); // undefined// 带 "new":new User(); // function User { ... }复制代码
登入後複製

它可以用在函數內部,來判斷該函數是被透過new 呼叫的“建構器模式”,還是沒被透過new 呼叫的“常規模式”。

我們也可以讓new 呼叫和常規呼叫做相同的工作,像這樣:

function User(name) {  if (!new.target) { // 如果你没有通过 new 运行我
    return new User(name); // ……我会给你添加 new
  }  this.name = name;
}let john = User("John"); // 将调用重定向到新用户alert(john.name); // John复制代码
登入後複製

這種方法有時被用在庫中以使語法更加靈活。這樣人們在呼叫函數時,無論是否使用了 new,程式都能運作。

不過,到處都使用它並不是一件好事,因為省略了 new 使得很難觀察到程式碼中正在發生什麼。而透過 new 我們都可以知道這創建了一個新物件。

建構器的 return

通常,建構子沒有 return 語句。它們的任務是將所有必要的東西寫入 this,並自動轉換為結果。

但是,如果這有一個return 語句,那麼規則就簡單了:

  • 如果return 傳回的是一個對象,則傳回這個對象,而不是this
  • 如果 return 回傳的是一個原始類型,則忽略。

換句話說,帶有物件的 return 傳回該對象,在所有其他情況下返回 this

例如,這裡return 透過傳回一個物件覆蓋this

function BigUser() {  this.name = "John";  return { name: "Godzilla" };  // <-- 返回这个对象}

alert( new BigUser().name );  // Godzilla,得到了那个对象复制代码
登入後複製

這裡有一個return 為空的例子(或者我們可以在它之後放置一個原始類型,沒有什麼影響):

function SmallUser() {  this.name = "John";  return; // <-- 返回 this}

alert( new SmallUser().name );  // John复制代码
登入後複製

通常構造器沒有return 語句。這裡我們主要為了完整性而提及回傳物件的特殊行為。

省略括號

順便說一下,如果沒有參數,我們可以省略new 後的括號:

let user = new User; // <-- 没有参数// 等同于let user = new User();复制代码
登入後複製

這裡省略括號不被認為是一種“好風格”,但是規範允許使用該語法。

建構器中的方法

使用建構子來建立物件會帶來很大的彈性。建構函數可能有一些參數,這些參數定義瞭如何建構物件以及要放入什麼。

当然,我们不仅可以将属性添加到 this 中,还可以添加方法。

例如,下面的 new User(name) 用给定的 name 和方法 sayHi 创建了一个对象:

function User(name) {  this.name = name;  this.sayHi = function() {
    alert( "My name is: " + this.name );
  };
}let john = new User("John");

john.sayHi(); // My name is: John/*
john = {
   name: "John",
   sayHi: function() { ... }
}
*/复制代码
登入後複製

类 是用于创建复杂对象的一个更高级的语法,我们稍后会讲到。

总结

  • 构造函数,或简称构造器,就是常规函数,但大家对于构造器有个共同的约定,就是其命名首字母要大写。
  • 构造函数只能使用 new 来调用。这样的调用意味着在开始时创建了空的 this,并在最后返回填充了值的 this

我们可以使用构造函数来创建多个类似的对象。

JavaScript 为许多内置的对象提供了构造函数:比如日期 Date、集合 Set 以及其他我们计划学习的内容。

对象,我们还会回来哒!

在本章中,我们只介绍了关于对象和构造器的基础知识。它们对于我们在下一章中,学习更多关于数据类型和函数的相关知识非常重要。

在我们学习了那些之后,我们将回到对象,在 info:prototypes 和 info:classes 章节中深入介绍它们。

作业题

先自己做题目再看答案。

1. 两个函数 — 一个对象

重要程度:⭐️⭐️

是否可以创建像 new A()==new B() 这样的函数 AB

function A() { ... }function B() { ... }let a = new A;let b = new B;

alert( a == b ); // true复制代码
登入後複製

如果可以,请提供一个它们的代码示例。

2. 创建 new Calculator

重要程度:⭐️⭐️⭐️⭐️⭐️

创建一个构造函数 Calculator,它创建的对象中有三个方法:

  • read() 使用 prompt 请求两个值并把它们记录在对象的属性中。
  • sum() 返回这些属性的总和。
  • mul() 返回这些属性的乘积。

例如:

let calculator = new Calculator();
calculator.read();

alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );复制代码
登入後複製

3. 创建 new Accumulator

重要程度:⭐️⭐️⭐️⭐️⭐️

创建一个构造函数 Accumulator(startingValue)

它创建的对象应该:

  • 将“当前 value”存储在属性 value 中。起始值被设置到构造器 startingValue 的参数。
  • read() 方法应该使用 prompt 来读取一个新的数字,并将其添加到 value 中。

换句话说,value 属性是所有用户输入值与初始值 startingValue 的总和。

下面是示例代码:

let accumulator = new Accumulator(1); // 初始值 1accumulator.read(); // 添加用户输入的 valueaccumulator.read(); // 添加用户输入的 valuealert(accumulator.value); // 显示这些值的总和复制代码
登入後複製

相关免费学习推荐:JavaScript(视频)

以上是JavaScript 建構函式和 'new' 運算子詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:juejin.im
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板