亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript知識(shí):構(gòu)造函數(shù)也是函數(shù)

 更新時(shí)間:2021年08月20日 10:30:53   作者:峰回路轉(zhuǎn)~  
構(gòu)造函數(shù)就是初始化一個(gè)實(shí)例對象,對象的prototype屬性是繼承一個(gè)實(shí)例對象。本文給大家分享javascript構(gòu)造函數(shù)詳解,對js構(gòu)造函數(shù)相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧

首先要明確的是構(gòu)造函數(shù)也是函數(shù)

我經(jīng)常使用構(gòu)造函數(shù)來創(chuàng)建實(shí)例對象,例如對象和數(shù)組的實(shí)例化可以通過相應(yīng)的構(gòu)造函數(shù)Object()和Array()完成。

構(gòu)造函數(shù)與普通函數(shù)在語法的定義上沒有任何區(qū)別,主要的區(qū)別體現(xiàn)在以下3點(diǎn)。

(1)構(gòu)造函數(shù)的函數(shù)名的第一個(gè)字母通常會(huì)大寫。按照慣例,構(gòu)造函數(shù)名稱的首字母都是要大寫的,非構(gòu)造函數(shù)則以小寫字母開頭。這是從面向?qū)ο缶幊陶Z言那里借鑒的,有助于在ECMAScript中區(qū)分構(gòu)造函數(shù)和普通函數(shù)。

(2)在函數(shù)體內(nèi)部使用this關(guān)鍵字,表示要生成的對象實(shí)例,構(gòu)造函數(shù)并不會(huì)顯式地返回任何值,而是默認(rèn)返回“this”。在下面的代碼段中,Person()函數(shù)并沒有使用return關(guān)鍵字返回任何信息,但是輸出的變量person1是一個(gè)具有name、age屬性值的Person實(shí)例。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
      //1.定義構(gòu)造函數(shù)
      function Person(name,age){
        this.age = age;
        this.name = name;
        this.sayName = function(){
            console.log(this.name);
        } 
      }
      // 2.生成實(shí)例對象
      var person1 = new Person('小蘇','18');
      // 3.打印實(shí)例對象
      console.log(person1);
  </script>
</body>
</html>

顯示效果如下


(3)作為構(gòu)造函數(shù)調(diào)用時(shí),必須與new操作符配合使用。這一點(diǎn)非常重要,任何函數(shù)只要使用new操作符調(diào)用就是構(gòu)造函數(shù),而不使用new操作符調(diào)用的函數(shù)就是普通函數(shù)。

1、構(gòu)造函數(shù)的定義與調(diào)用

構(gòu)造函數(shù)又稱為自定義函數(shù),以函數(shù)的形式為自己的對象類型定義屬性和方法。

舉例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
      //1.定義構(gòu)造函數(shù)
      function Person(name,age){
        this.age = age;
        this.name = name;
        this.sayName = function(){
            console.log(this.name);
        } 
      }
      // 2.生成實(shí)例對象
      var person1 = new Person('小蘇','18');
      // 3.調(diào)用方法
      person1.sayName();
  </script>
</body>
</html>

2、new關(guān)鍵字的用途

構(gòu)造函數(shù)在執(zhí)行時(shí),會(huì)執(zhí)行以下4步:

  • 通過new關(guān)鍵字(操作符)創(chuàng)建實(shí)例對象,會(huì)在內(nèi)存中創(chuàng)建一個(gè)新的地址。
  • 為構(gòu)造函數(shù)中的this確定指向,指向?qū)嵗谋旧怼?/li>
  • 執(zhí)行構(gòu)造函數(shù)代碼,為實(shí)例添加屬性。
  • 返回這個(gè)新創(chuàng)建的對象。

以前面生成person1實(shí)例的代碼為例。

第一步:為person1實(shí)例在內(nèi)存中創(chuàng)建一個(gè)新的地址。

第二步:確定person1實(shí)例的this指向,指向person本身。

第三步:為person1實(shí)例添加name、age和sayName屬性,其中sayName屬性值是一個(gè)函數(shù)。

第四步:返回這個(gè)person1實(shí)例。

舉個(gè)實(shí)例

var person1 = new Person("Bob", 18);

這行代碼,等價(jià)于

// 演示 new 的功能
function Person(name,age) {
  // 1.創(chuàng)建一個(gè)新對象
  var instance = new Object();
  // 2.將函數(shù)內(nèi)部的 this 指向了這個(gè)新對象
  this = instance;
  // 3.執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼
  this.name = name;
  this.age = age;
  this.sayName = function () {
    console.log(this.name);
  };
  // 4.將新對象作為返回值
  return instance;
}

這就意味著,將instance 賦值給 person1,即person1 = instance。實(shí)際上又是這樣的:

// 演示 new 的功能
function Person(name,age) {
  // 1.創(chuàng)建一個(gè)新對象
  var person1 = new Object();
  // 2.將函數(shù)內(nèi)部的 this 指向了這個(gè)新對象
  this = person1;
  // 3.執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼
  this.name = name;
  this.age = age;
  this.sayName = function () {
    console.log(this.name);
  };
  // 4.將新對象作為返回值
  return person1;
}

3、構(gòu)造函數(shù)的問題:浪費(fèi)內(nèi)存

基本事實(shí):不同實(shí)例中的sayName屬性是不同的。舉個(gè)例子:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 1.自定義構(gòu)造函數(shù)
    function Person(name,age) {
      this.name = name;
      this.age = age;
      // this 內(nèi)部的 type 屬性值是不變的
      this.type = "human";
      // 每個(gè)對象的 sayName 方法也是一樣的
      this.sayName = function () {
        console.log(this.name);
      };
    }
    
    var person1 = new Person('Bob',18);
    var person2 = new Person('Mike',20);
    // 2,判斷各自的方法是否是同一個(gè)函數(shù)
    console.log(person1.sayName === person2.sayName); // false
  </script>
</body>
</html>

解釋:通過console.log(person1.sayName === person2.sayName)方法可判斷兩個(gè)函數(shù)是否是是同一個(gè),顯然這不是同一個(gè)函數(shù),那么兩個(gè)函數(shù)就占用了兩個(gè)內(nèi)存空間,就會(huì)造成內(nèi)存的浪費(fèi)。

那如何解決函數(shù)占用內(nèi)存的辦法呢?答案是將對象內(nèi)部函數(shù)提取出來作為公共函數(shù)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 解決方法1: 將公共的函數(shù)提取到構(gòu)造函數(shù)之外
    function sayName() {
      console.log(this.name);
    }
    function sayAge() {
      console.log(this.age);
    }
    //1.自定義對象
    function Person(name,age) {
      this.name = name;
      this.age = age;
      // this 內(nèi)部的 type 屬性值是不變的
      this.type = "human";
      // 每個(gè)對象的 sayName 方法也是一樣的
      this.sayName = sayName;
      this.sayAge = sayAge;
    }
    //2.實(shí)例化對象
    var person1 = new Person('Bob',18);
    var person2 = new Person('Mike',20);
    console.log(person1.sayName === person2.sayName); // true
    </script>
</body>
</html>

此時(shí),也存在一個(gè)問題,如果有多個(gè)公共函數(shù),需要在外部創(chuàng)建多個(gè)函數(shù),可能會(huì)造成命名沖突

解決辦法,將多個(gè)公共的函數(shù)封裝到一個(gè)對象

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 3.將多個(gè)公共的函數(shù)封裝到一個(gè)對象
    var fns = {
      sayName : function () {
        console.log(this.name);
      },
      sayAge : function () {
        console.log(this.age);
      }      
    };    
    // 1.自定義對象
    function Person(name,age) {
      this.name = name;
      this.age = age;
      this.type = "human";
      this.sayName = fns.sayName;
      this.sayAge = fns.sayAge;
    }
    // 2.生成對象實(shí)例
    var person1 = new Person("Bob",18);
    var person2 = new Person("Mike",20);

    // person1.sayName();
    console.log(person1.sayName === person2.sayName);
    console.log(person1.sayAge === person2.sayAge);
  </script>
</body>
</html>

解釋:將多個(gè)函數(shù)封裝成一個(gè)對象即可解決函數(shù)名可能沖突的問題。

通過這種設(shè)置全局訪問的函數(shù),這樣就可以被所有實(shí)例訪問到,而不用重復(fù)創(chuàng)建。

但是這樣也會(huì)存在一個(gè)問題,如果為一個(gè)對象添加的所有函數(shù)都處理成全局函數(shù),這樣并無法完成對一個(gè)自定義類型對象的屬性封裝(言外之意。指的是全局函數(shù)只可以封裝函數(shù),但無法封裝屬性,因?yàn)閷傩苑庋b在函數(shù)外面,要定義為全局變量,才可以去調(diào)用,這反而會(huì)污染全局變量),因此這不是一個(gè)好的解決辦法。

此時(shí),便引用原型的概念,使用原型概念可以很好解決這個(gè)問題,可以很好解決這個(gè)問題。

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

最新評論