最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript知識:構造函數也是函數

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

首先要明確的是構造函數也是函數

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

構造函數與普通函數在語法的定義上沒有任何區(qū)別,主要的區(qū)別體現在以下3點。

(1)構造函數的函數名的第一個字母通常會大寫。按照慣例,構造函數名稱的首字母都是要大寫的,非構造函數則以小寫字母開頭。這是從面向對象編程語言那里借鑒的,有助于在ECMAScript中區(qū)分構造函數和普通函數。

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

<!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.定義構造函數
      function Person(name,age){
        this.age = age;
        this.name = name;
        this.sayName = function(){
            console.log(this.name);
        } 
      }
      // 2.生成實例對象
      var person1 = new Person('小蘇','18');
      // 3.打印實例對象
      console.log(person1);
  </script>
</body>
</html>

顯示效果如下


(3)作為構造函數調用時,必須與new操作符配合使用。這一點非常重要,任何函數只要使用new操作符調用就是構造函數,而不使用new操作符調用的函數就是普通函數。

1、構造函數的定義與調用

構造函數又稱為自定義函數,以函數的形式為自己的對象類型定義屬性和方法。

舉例:

<!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.定義構造函數
      function Person(name,age){
        this.age = age;
        this.name = name;
        this.sayName = function(){
            console.log(this.name);
        } 
      }
      // 2.生成實例對象
      var person1 = new Person('小蘇','18');
      // 3.調用方法
      person1.sayName();
  </script>
</body>
</html>

2、new關鍵字的用途

構造函數在執(zhí)行時,會執(zhí)行以下4步:

  • 通過new關鍵字(操作符)創(chuàng)建實例對象,會在內存中創(chuàng)建一個新的地址。
  • 為構造函數中的this確定指向,指向實例的本身。
  • 執(zhí)行構造函數代碼,為實例添加屬性。
  • 返回這個新創(chuàng)建的對象。

以前面生成person1實例的代碼為例。

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

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

第三步:為person1實例添加name、age和sayName屬性,其中sayName屬性值是一個函數。

第四步:返回這個person1實例。

舉個實例

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

這行代碼,等價于

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

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

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

3、構造函數的問題:浪費內存

基本事實:不同實例中的sayName屬性是不同的。舉個例子:

<!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.自定義構造函數
    function Person(name,age) {
      this.name = name;
      this.age = age;
      // this 內部的 type 屬性值是不變的
      this.type = "human";
      // 每個對象的 sayName 方法也是一樣的
      this.sayName = function () {
        console.log(this.name);
      };
    }
    
    var person1 = new Person('Bob',18);
    var person2 = new Person('Mike',20);
    // 2,判斷各自的方法是否是同一個函數
    console.log(person1.sayName === person2.sayName); // false
  </script>
</body>
</html>

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

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

<!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: 將公共的函數提取到構造函數之外
    function sayName() {
      console.log(this.name);
    }
    function sayAge() {
      console.log(this.age);
    }
    //1.自定義對象
    function Person(name,age) {
      this.name = name;
      this.age = age;
      // this 內部的 type 屬性值是不變的
      this.type = "human";
      // 每個對象的 sayName 方法也是一樣的
      this.sayName = sayName;
      this.sayAge = sayAge;
    }
    //2.實例化對象
    var person1 = new Person('Bob',18);
    var person2 = new Person('Mike',20);
    console.log(person1.sayName === person2.sayName); // true
    </script>
</body>
</html>

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

解決辦法,將多個公共的函數封裝到一個對象

<!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.將多個公共的函數封裝到一個對象
    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.生成對象實例
    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>

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

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

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

此時,便引用原型的概念,使用原型概念可以很好解決這個問題,可以很好解決這個問題。

總結

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

相關文章

  • 一文了解JavaScript用Element?Traversal新屬性遍歷子元素

    一文了解JavaScript用Element?Traversal新屬性遍歷子元素

    這篇文章主要介紹了一文了解JavaScript用Element?Traversal新屬性遍歷子元素,文章圍繞Element?Traversal新屬性的相關資料展開詳細內容,需要的朋友可以參考一下,希望對大家有所幫助
    2021-11-11
  • 微信小程序 教程之注冊頁面

    微信小程序 教程之注冊頁面

    這篇文章主要介紹了微信小程序 注冊頁面的相關資料,需要的朋友可以參考下
    2016-10-10
  • JS前端使用canvas實現物體的點選示例

    JS前端使用canvas實現物體的點選示例

    這篇文章主要為大家介紹了JS前端使用canvas實現物體的點選示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • 一篇文章學會jsBridge的運行機制

    一篇文章學會jsBridge的運行機制

    JSBridge是一座用JavaScript搭建起來的橋,搭建這座橋的目的也很簡單,讓native可以調用web的js代碼,讓web可以 “調用” 原生的代碼。本文主要通過分析源碼講解jsBridge的運行機制,感興趣的朋友一起來看看吧
    2021-09-09
  • three.js-結合dat.gui實現界面可視化修改及調試詳解

    three.js-結合dat.gui實現界面可視化修改及調試詳解

    這篇文章主要為大家介紹了three.js-結合dat.gui實現界面可視化修改及調試詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • ECharts的三維可視化及在微信小程序中使用示例

    ECharts的三維可視化及在微信小程序中使用示例

    這篇文章主要為大家介紹了ECharts的三維可視化及在微信小程序中使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • 微信小程序 加載 app-service.js 錯誤解決方法

    微信小程序 加載 app-service.js 錯誤解決方法

    這篇文章主要介紹了微信小程序 加載 app-service.js 錯誤詳解的相關資料,在開發(fā)微信小程序過程中出現了app-services.js的錯誤,并解決此問題,需要的朋友可以參考下
    2016-10-10
  • 前端JavaScript大管家 package.json

    前端JavaScript大管家 package.json

    這篇文章主要介紹了前端JavaScript大管家 package.json,在每個前端項目中,都有package.json文件,它是項目的配置文件,常見的配置有配置項目啟動、打包命令,聲明依賴包等,下面我們就來學習 package.json的詳細內容,需要的朋友可以參考一下
    2021-10-10
  • Rollup的插件機制及構建流程深入解析

    Rollup的插件機制及構建流程深入解析

    這篇文章主要為大家介紹了Rollup的插件機制及構建流程深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • 將HTML自動轉為JS代碼

    將HTML自動轉為JS代碼

    將HTML自動轉為JS代碼...
    2006-06-06

最新評論

达尔| 武清区| 岳池县| 新泰市| 明水县| 高要市| 长海县| 开鲁县| 泗洪县| 将乐县| 新民市| 广东省| 含山县| 北宁市| 高台县| 阿克| 家居| 大足县| 宜君县| 定南县| 平谷区| 衡阳县| 阿坝| 甘孜| 定陶县| 涿鹿县| 嘉禾县| 唐海县| 花垣县| 民权县| 哈巴河县| 察隅县| 南安市| 双柏县| 岳西县| 洛浦县| 贺州市| 方城县| 崇义县| 水城县| 深泽县|