日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

JavaScript高级笔记_002_构造函数和原型

發布時間:2023/12/14 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript高级笔记_002_构造函数和原型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JavaScript高級筆記_002_構造函數和原型

  • 構造函數和原型
    • 構造函數和原型
      • 概述
      • 構造函數
      • 構造函數的問題
      • 構造函數原型`prototype`
      • 對象原型`__proto__` (四個下劃線)
      • `constructor` 構造函數
      • 構造函數,實例,原型對象三者之間的關系
      • 原型鏈
      • `Javascript` 的成員查找機制(規則)
      • 原型對象`this` 指向
      • 擴展內置對象
    • 繼承
      • `call()`
      • 借用構造函數繼承父類型屬性
      • 借用原型對象繼承父類型方法
    • ES5中的新增方法
      • ES5新增了一些方法,可以很方便的操作數組或者字符串,這些方法主要包括:
      • 數組方法
        • 查詢商品案例
      • 字符串方法
      • 對象方法

構造函數和原型

課程鏈接:

https://www.bilibili.com/video/BV1KJ411x7X7?p=23

構造函數和原型

概述

在典型的OOP語言中(如Java),都存在類的概念,類就是對象的模板,對象就是類的實例,但在ES6之前,JS中并沒有引入類的概念

ES6,全稱ECMAscript6.0,2015.06發版。但是目前瀏覽器的JavaScript版本都是ES5版本,大多數的高版本的瀏覽器也支持ES6,不過只實現了ES6的部分特性和功能

在ES6之前,對象不是基于類創建的,而是一種成為構造函數的特殊函數來定義對象和他的特征

創建對象可以通過以下三種方式:

  • 對象字面量

  • new Object()

  • 自定義構造函數

    function Star(uname, age) {this.uname = uname;this.age = age;this.sing = function() {console.log('我會唱歌');} }var ldh = new Star('劉德華', 18); ldh.sing();
  • 構造函數

    構造函數是一種特殊的函數,主要用來初始化對象,即為對象成員變量賦初始值,它總與new 一起使用。我們可以把對象中的一些公共屬性和方法抽取出來,然后封裝到這個函數里面

    在JS中,使用構造函數時要注意一下兩點:

  • 構造函數用于創建某一類對象,其首字母要大寫
  • 構造函數一定要和new一起使用才有意義
  • new** 在執行時會做四件事情:**

  • 在內存中創建一個空的對象
  • 讓this指向這個新的對象
  • 執行構造函數里面的代碼,給這個新對象添加屬性和方法
  • 返回這個新對象(所以構造函數里面不需要return )
  • javascript 的構造函數中可以添加一些成員,可以在構造函數本身上添加,也可以在構造函數內部的this 上添加。通過這兩種方式添加的成員,就分別成為靜態成員和實例成員

    • 靜態成員:在構造函數本身上添加的成員稱為靜態成員,只能有構造函數本身來訪問
    • 實例成員:在構造函數內部創建的成員稱為實例成員,只能由實例化的對象來訪問
    function Star(uname, age) {this.uname = uname;this.age = age;this.sing = function() {console.log('我會唱歌');} }var ldh = new Star('劉德華', 18); ldh.sing();

    構造函數的問題

    構造函數方法很好用,但是存在內存浪費的問題

    構造函數原型prototype

    構造函數通過原型分配的函數是所有對象所共享的

    Javascript規定,每一個構造函數都有一個prototype 屬性,指向另一個對象。注意這個prototype 就是一個對象,這個對象的所有屬性和方法,都會被構造函數所擁有

    我們可以把那些不變的方法,直接定義在**prototype**對象上,這樣所有對象的實例就可以共享這些方法

    語法

    function Star(uname, age) {this.uname = uname;this.age = age; }Star.prototype.sing = function() {console.log('我唱歌'); }

    問答?

  • 原型是什么?

    一個對象,我們稱prototype 為原型對象

  • 原型的作用是什么?

    共享方法

  • 一般情況下,我們的公共屬性定義到構造函數里面,公共的方法我們就放到原型對象身上

    對象原型__proto__ (四個下劃線)

    對象都會有一個屬性__proto__ 指向構造函數的prototype 原型對象,之所以我們對象可以使用構造函數prototype 原型對象的屬性和方法,就是因為對象有__proto__ 原型的存在

    • __proto__ 對象原型和原型對象prototype 是等價的
    • __proto__ 對象原型的意義就在于為對象的查找機制提供了一個方向,或者說一條路線,但是他是一個非標準屬性,因此在實際開發中,不可以使用這個屬性,它只是內部指向原型對象prototype

    方法的查找規則:首先看對對象身上是否有這個方法,如果有就執行這個對象上的方法,如果沒有這個方法,因為__proto__ 的存在,就去構造函數原型對象prototype 身上去查找這個方法

    constructor 構造函數

    對象原型__proto__ 和構造函數prototype原型對象里面都有一個屬性constructor 屬性,constructor 我們稱為構造函數,因為它指向構造函數本身

    constructor 主要用于記錄該對象引用于哪個構造函數,它可以讓原型對象重新指向原來的構造函數

    function Star(uname, age) {this.name = uname;this.age = age; } Star.prototype.sing = function() {console.log('我會唱歌'); }; Star.prototype.movie= function() {console.log('我會演電影'); } var ldh = new Star(); console.log(ldh.__proto__.constructor); console.log(Star.prototype.constructor);

    很多情況下,我們需要手動的利用constructor 這個屬性指回原來的構造函數

    function Star(uname, age) {this.name = uname;this.age = age; } Star.prototype = {// 如果我們修改了原來原型對象,給原型對象賦值的是一個對象,則必須手動利用constructor指回原來的構造函數// 手動的利用constructor 這個屬性指回原來的構造函數constructor : Star;sing : function() {console.log('我會唱歌');},movie : function() {console.log('我會演電影');} }var ldh = new Star(); console.log(ldh.__proto__.constructor); console.log(Star.prototype.constructor);

    如果我們修改了原來原型對象,給原型對象賦值的是一個對象,則必須手動利用constructor指回原來的構造函數

    構造函數,實例,原型對象三者之間的關系

    原型鏈

    Javascript 的成員查找機制(規則)

  • 當訪問一個對象的屬性(包括方法)時,首先查找這個對象本身有沒有該屬性
  • 如果沒有就查找它的原型(也就是__proto__ 指向的prototype 原型對象)
  • 如果還沒有就查找原型對象的原型(Object 的原型對象
  • 依次類推一直找到Object 為止(NULL)
  • __proto__ 對象原型的意義就在于為對象成員查找機制提供一個方向,或者說一條路線
  • 原型對象this 指向

  • 在構造函數中,里面的this 指向的是對象實例ldh
  • 原型對象函數里面的this 指向的是實例對象ldh
  • 擴展內置對象

    可以通過原型對象,對原來的內置對象進行擴展定義的方法。比如給數組增加自定義求和的功能

    Array.prototype.sum = function() {for(var i = 0; i < this.length; i++) {var sum = 0;sum += this[i];}return sum; }var arr = [1,2,3]; console.log(arr.sum());

    數組和字符串內置對象不能給原型對象覆蓋操作Array.prototype = {} ,只能是Array.prototype.xxx = function() {} 的方式

    繼承

    ES6之前并沒有給我們提供extends 繼承。我們可以通過構造函數 + 原型對象模擬實現繼承,被稱為組合繼承

    call()

    調用這個函數并且修改函數運行時的this 指向

    語法

    fun.call(thisArg, arg1, arg2, ...);

    參數:

    • thisArg:當前嗲用函數this的指向對象
    • arg1, arg2:傳遞的其他參數
    function fn() {console.log('我想喝咖啡'); }var o = {name = 'andy' }; // 1 call()可以調用函數 fn.call(); // 2 call()可以改變函數的this的指向 fn.call(o); // 此時這個函數的this指向的就是o這個對象

    借用構造函數繼承父類型屬性

    核心原理:通過call() 把父類型的this 指向子類型的this ,這樣就可以實現子類型繼承父類型的屬性

    // 借用父構造函數繼承屬性 // 1 父構造函數 function Father(uname, age) {// this指向父構造函數的對象實例this.uname = uname;this.age = age; } // 2 子構造函數 function Son(uname, age, score) {// this指向子構造函數的對象實例Father.call(this, uname, age);this.score = score; }var son = new Son('劉德華'); console.log(son);

    借用原型對象繼承父類型方法

    // 借用父構造函數繼承屬性 // 1 父構造函數 function Father(uname, age) {// this指向父構造函數的對象實例this.uname = uname;this.age = age; } Father.prototype.money = function() {console.log(100000); } // 2 子構造函數 function Son(uname, age, score) {// this指向子構造函數的對象實例Father.call(this, uname, age);this.score = score; }// 核心代碼 Son.prototype = new Father(); Son.prototype.constructor = Son;Son.prototype.exam = function() {conle.log('我要考試'); }var son = new Son('劉德華'); console.log(son);

    ES5中的新增方法

    ES5新增了一些方法,可以很方便的操作數組或者字符串,這些方法主要包括:

    • 數組方法
    • 字符串方法
    • 對象方法

    數組方法

    迭代(遍歷)方法:forEach(), map(), filter(), some() ,every();

    forEach** 語法**

    array.forEach(function(currentValue, index, arr));

    參數:

    • currentValue :數組當前項的值
    • index :數組當前項的索引
    • arr :數組對象本身

    例子:

    var arr = [1,2,3]; var sum = 0; arr.forEach(function(value, index, array) {sum += value; });

    filter() ** 語法**

    array.filter(function(currentValue, index, arr));
    • filter() 方法創建一個新的數組,新的數組中的元素是通過檢查指定數組中符合條件的所有元素,主要用于篩選數組
    • 注意它返回的是一個新的數組
    • currentValue :數組當前項的值
    • index :數組當前項的索引
    • arr :數組對象本身
    var arr = [12, 24, 6, 77, 88]; var newArr = arr.filter(function(value, index, array) {// 篩選大于20的數return value >= 20; });

    some()** 語法**

    array.some(function(currentValue, index, arr));
    • some() 方法用于檢測數組中的元素是否滿足指定條件。通俗點講就是查找數組中是否有滿足條件的元素
    • 注意它返回的是布爾值,如果查找到這和個元素,就返回true ,如果找不到就返回false
    • 如果找到第一個滿足條件的元素,則終止循環,不再繼續尋找
    • currentValue :數組當前項的值
    • index :數組當前項的索引
    • arr :數組對象本身
    var arr = [10, 3, 20, 33]; var flag = some(function(value) {// 判斷數組中是否有大于等于20的數return value >= 20; }); console.log(flag);

    查詢商品案例

  • 把數據渲染到頁面中
  • 根據價格顯示數據
  • 根據商品名稱顯示數據
  • 字符串方法

    tirm() 方法會從一個字符串的兩段刪除空白字符

    語法

    str.trim();

    tirm() 方法并不影響原字符串本身,它返回的是一個新的字符串

    對象方法

  • Object.keys() 用于獲取自身對象的所有的屬性
    語法

    Object.keys(obj);
    • 效果類似for…in
    • 返回一個由屬性名組成的數組
  • Object.defineProperty() 定義對象中新屬性或修改原有的屬性
    語法

    Object.defineProperty(obj, prop, descriptor);
    • obj:必需。目標對象
    • prop:必需。徐定義或修改的屬性的名字
    • descriptor:必需。目標屬性所擁有的特性,以對象形式{}書寫
      • value:設置屬性的值,默認為undefined
      • writable:值是否可以重寫。true|false,默認為false
      • enumerable:目標屬性是否可以被枚舉。true|false,默認為false
      • configurable:目標屬性是都可以被刪除或者是否可以再次修改特性ture|false,默認為false
    var obj = {id:1,pname:'小米',price:1999 }; // 添加 Object.defineProperty(obj, 'num', {value:1000 });// 修改 Object.defineProperty(obj, 'price', {value:999 });// 禁止修改 id的值 Object.defineProperty(obj, 'id', {writable:false; });Object.defineProperty(obj, 'address', {value:'中國山東藍翔技校xx單元',writable:false,// 禁止遍歷address屬性enumerable:false,// 禁止刪除address屬性configurable:false });
  • 總結

    以上是生活随笔為你收集整理的JavaScript高级笔记_002_构造函数和原型的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。