【前端 javascript 高級(jí)】 02 - 構(gòu)造函數(shù)和原型+繼承+ES5新增方法

1. 構(gòu)造函數(shù)和原型

1.1 對(duì)象的三種創(chuàng)建方式--復(fù)習(xí)

  1. 對(duì)象字面量的方式 :
let obj = {
    name: '張三',
    age: 23,
    sayHi: function () {
      console.log('hi!');
    }
  }

  console.log(obj.name);
  obj.sayHi();
  1. 使用 new 關(guān)鍵字的方式創(chuàng)建對(duì)象 :
let object = new Object();
  object.name = '李四';
  object.age = 24;
  object.sayHello = function () {
    console.log('say hello');
  }

  object.sayHello();
  1. 使用構(gòu)造函數(shù)創(chuàng)建對(duì)象:
function Star(name, age) {
    this.name = name;
    this.age = age;
    this.print = function () {
      console.log(name + age);
    }
  }

  let star = new Star('王五', 35);
  star.print();

1.2 靜態(tài)成員和實(shí)例成員

實(shí)例成員
  1. 實(shí)例成員就是構(gòu)造函數(shù)內(nèi)部通過 this 添加的成員 如下列代碼中 uname age sing 就是實(shí)例成員,實(shí)例成員只能通過實(shí)例化的對(duì)象來訪問。
 // 實(shí)例成員就是構(gòu)造函數(shù)內(nèi)部通過 this 添加的成員
  function Star(name, age) {

    this.name = name;
    this.age = age;

    this.sayHello = function () {
      console.log('say hello');
    };
  }

  // 實(shí)例成員只能通過實(shí)例化的對(duì)象來訪問
  let star = new Star('張三', 23);
  console.log(star.name);
  console.log(star.age);
  // 不可以通過構(gòu)造函數(shù)來訪問實(shí)例成員
  console.log(Star.age); // undefined

  // 靜態(tài)成員是在構(gòu)造函數(shù)本身上添加的成員,靜態(tài)成員只能通過構(gòu)造函數(shù)訪問不能通過實(shí)例對(duì)象訪問
  Star.sex = '男';

  console.log(star.sex); // undefined 實(shí)例對(duì)象調(diào)用靜態(tài)成員 

  console.log(Star.sex); // 男  構(gòu)造函數(shù)調(diào)用靜態(tài)成員
靜態(tài)成員
  1. 靜態(tài)成員 在構(gòu)造函數(shù)本身上添加的成員 如下列代碼中 sex 就是靜態(tài)成員,靜態(tài)成員只能通過構(gòu)造函數(shù)來訪問。
function Star(uname, age) {
     this.uname = uname;
     this.age = age;
     this.sing = function() {
     console.log('我會(huì)唱歌');
    }
}
Star.sex = '男';
var ldh = new Star('劉德華', 18);
console.log(Star.sex);//靜態(tài)成員只能通過構(gòu)造函數(shù)來訪問

1.3 構(gòu)造函數(shù)的問題

  1. 構(gòu)造函數(shù)方法很好用,但是存在浪費(fèi)內(nèi)存的問題。
公共的方法會(huì)各自占用一塊內(nèi)存

1.4 構(gòu)造函數(shù)原型 prototype

  1. 構(gòu)造函數(shù)通過原型分配的函數(shù)是所有對(duì)象所共享的。

  2. JavaScript 規(guī)定,每一個(gè)構(gòu)造函數(shù)都有一個(gè) prototype 屬性,指向另一個(gè)對(duì)象。注意這個(gè) prototype 就是一個(gè)對(duì)象,這個(gè)對(duì)象的所有屬性和方法,都會(huì)被構(gòu)造函數(shù)所擁有。

  3. 我們可以把那些不變的方法,直接定義在 prototype 對(duì)象上,這樣所有對(duì)象的實(shí)例就可以共享這些方法。

  /**
   * 構(gòu)造函數(shù)
   * */
  function Star(name, age) {
    this.name = name;
    this.age = age;
    /**
     * 還是會(huì)優(yōu)先調(diào)用它
     *
     */
    /*this.sing = function () {
      console.log('我會(huì)唱歌嗎?');
    };*/
  }

  console.dir(Star);

  // 在構(gòu)造函數(shù)的原型對(duì)象里面 添加共享的方法
  // 原型是一個(gè)對(duì)象是每個(gè)構(gòu)造函數(shù)中都會(huì)存在的一個(gè)對(duì)象
  // 原型的作用是: 共享方法
  // 一般情況下,我們的公共屬性定義在構(gòu)造函數(shù)中,但是公共的方法我們需要放到原型對(duì)象身上
  Star.prototype.sing = function () {
    console.log('我會(huì)唱歌');
  };

  let star = new Star('黎明', 23);
  let s = new Star('張華自', 23);
  console.log(star.sing() === s.sing()); // true

1.5 對(duì)象原型

對(duì)象實(shí)例都會(huì)有一個(gè)屬性 __proto__(對(duì)象原型)指向構(gòu)造函數(shù)的 prototype 原型對(duì)象,之所以我們對(duì)象可以使用構(gòu)造函數(shù) prototype 原型對(duì)象的屬性和方法,就是因?yàn)閷?duì)象有__proto__原型的存在。
__proto__對(duì)象原型和原型對(duì)象prototype 是等價(jià)的 __proto__對(duì)象原型的意義就在于為對(duì)象的查找機(jī)制提供一個(gè)方向,或者說一條路線,但是它是一個(gè)非標(biāo)準(zhǔn)屬性,因此實(shí)際開發(fā)中,不可以使用這個(gè)屬性,它只是內(nèi)部指向原型對(duì)象 prototype。

原型對(duì)象和對(duì)象原型的關(guān)系

  function Star(name, age) {

    this.name = name;
    this.age = age;

  }
  /**
   * 在原型對(duì)象上添加一個(gè)共享方法
   */
  Star.prototype.sing = function () {
    console.log('我會(huì)唱歌');
  }

  let ldh = new Star('劉德華', 66);
  // 對(duì)比原型對(duì)象和對(duì)象原型
  console.log(ldh.__proto__ === Star.prototype); // true

1.6 constructor構(gòu)造函數(shù)

對(duì)象原型( __proto__)和構(gòu)造函數(shù)(prototype)原型對(duì)象里面都有一個(gè)屬性 constructor 屬性 ,constructor 我們稱為構(gòu)造函數(shù),因?yàn)樗富貥?gòu)造函數(shù)本身。
constructor 主要用于記錄該對(duì)象引用于哪個(gè)構(gòu)造函數(shù),它可以讓原型對(duì)象重新指向原來的構(gòu)造函數(shù)。
一般情況下,對(duì)象的方法都在構(gòu)造函數(shù)的原型對(duì)象中設(shè)置。如果有多個(gè)對(duì)象的方法,我們可以給原型對(duì)象采取對(duì)象形式賦值,但是這樣就會(huì)覆蓋構(gòu)造函數(shù)原型對(duì)象原來的內(nèi)容,這樣修改后的原型對(duì)象 constructor 就不再指向當(dāng)前構(gòu)造函數(shù)了。此時(shí),我們可以在修改后的原型對(duì)象中,添加一個(gè) constructor 指向原來的構(gòu)造函數(shù)。

如果我們修改了原來的原型對(duì)象,給原型對(duì)象賦值的是一個(gè)對(duì)象,則必須手動(dòng)的利用constructor指回原來的構(gòu)造函數(shù)如:

 function Star(uname, age) {
     this.uname = uname;
     this.age = age;
 }
 // 很多情況下,我們需要手動(dòng)的利用constructor 這個(gè)屬性指回 原來的構(gòu)造函數(shù)
 Star.prototype = {
 // 如果我們修改了原來的原型對(duì)象,給原型對(duì)象賦值的是一個(gè)對(duì)象,則必須手動(dòng)的利用constructor指回原來的構(gòu)造函數(shù)
   constructor: Star, // 手動(dòng)設(shè)置指回原來的構(gòu)造函數(shù)
   sing: function() {
     console.log('我會(huì)唱歌');
   },
   movie: function() {
     console.log('我會(huì)演電影');
   }
}
var zxy = new Star('張學(xué)友', 19);
console.log(zxy)

以上代碼運(yùn)行結(jié)果,設(shè)置constructor屬性如圖:

手動(dòng)設(shè)置constructor屬性指回原來的構(gòu)造函數(shù)

如果未設(shè)置constructor屬性,如圖:

如果未設(shè)置constructor屬性

1.7 原型鏈

  1. 每一個(gè)實(shí)例對(duì)象又有一個(gè)proto 屬性,指向的構(gòu)造函數(shù)的原型對(duì)象,構(gòu)造函數(shù)的原型對(duì)象也是一個(gè)對(duì)象,也有proto屬性,這樣一層一層往上找就形成了原型鏈。
原型鏈
 function Star(name, age) {
    this.name = name;
    this.age = age;
  }

  console.log(Star.prototype); // 構(gòu)造函數(shù)中的原型對(duì)象 原型對(duì)象中有對(duì)象原型 __proto__ 指向 Object
  /**
   * Star.prototype.__proto__ 構(gòu)造函數(shù)中原型對(duì)象 的對(duì)象原型 指向 Object 的原型對(duì)象
   * 我們Star原型對(duì)象里面
   */
  console.log(Star.prototype.__proto__ === Object.prototype);
  console.log(Object.prototype.__proto__); // null  Object的 原型對(duì)象的對(duì)象原型指向的是 null
  console.dir(Object);

1.8 構(gòu)造函數(shù)實(shí)例和原型對(duì)象三角關(guān)系

1.構(gòu)造函數(shù)的prototype屬性指向了構(gòu)造函數(shù)原型對(duì)象;

2.實(shí)例對(duì)象是由構(gòu)造函數(shù)創(chuàng)建的,實(shí)例對(duì)象的__proto__屬性指向了構(gòu)造函數(shù)的原型對(duì)象;

3.構(gòu)造函數(shù)的原型對(duì)象的constructor屬性指向了構(gòu)造函數(shù),實(shí)例對(duì)象的原型的constructor屬性也指向了構(gòu)造函數(shù)。

構(gòu)造函數(shù)實(shí)例和原型對(duì)象三角關(guān)系
  function Star(name, age) {

    this.name = name;
    this.age = age;
  }

  let star = new Star('張三', 23);

  // 1. 構(gòu)造函數(shù)中的 prototype 指向了原型對(duì)象
  console.log(Star.prototype);

  // 2. 原型對(duì)象中constructor指向了構(gòu)造函數(shù)
  console.log(Star.prototype.constructor);

  // 3. 構(gòu)造函數(shù)指向?qū)ο髮?shí)例 ,對(duì)象實(shí)例中的 __proto__(對(duì)象原型) 指向了原型對(duì)象
  console.log(star.__proto__);
  console.log(star.__proto__.constructor);

1.9 原型鏈和成員的查找機(jī)制

  1. 任何對(duì)象都有原型對(duì)象,也就是prototype 屬性,任何原型對(duì)象也是一個(gè)對(duì)象,該對(duì)象就有proto 屬性,這樣一層一層往上找,就形成了一條鏈,我們稱此為原型鏈;
  • 當(dāng)訪問一個(gè)對(duì)象的屬性(包括方法)時(shí),首先查找這個(gè)對(duì)象自身有沒有該屬性。
  • 如果沒有就查找它的原型(也就是__proto__指向的 prototype原型對(duì)象)。
  • 如果還沒有就查找原型對(duì)象的原型(Object的原型對(duì)象)。
  • 依此類推一直找到 Object 為止(null)。
  • __proto__對(duì)象原型的意義就在于為對(duì)象成員查找機(jī)制提供一個(gè)方向,或者說一條路線。
 /**
   * @param name
   * @param age
   * @constructor
   */
  function Star(name, age) {
    this.name = name;
    this.age = age;
  }

  Star.prototype.sing = function () {
    console.log('我會(huì)唱噶');
  }

  Star.height = 178;
  console.log(Star.height);
  let star = new Star('張三', 23);

  // star.sex = '男'; // 1.先在實(shí)例對(duì)象上查找
  // Star.prototype.sex = '男'; // 2. 再在原型對(duì)象上找
  Object.prototype.sex = '女'; // 3. 最后在Object的原型對(duì)象上找
  console.log(star.sex);
  star.sing();
  star.sex = '男';
  console.log(star.sex); // 男
  // 對(duì)象成員查找是根據(jù)原型鏈的機(jī)制進(jìn)行查找
  console.log(Object.prototype); // 這里面有個(gè)toString方法
  console.log(Star.prototype);
  console.log(star.toString());

1.10 原型對(duì)象中this指向

  1. 構(gòu)造函數(shù)中的this和原型對(duì)象的this,都指向我們new出來的實(shí)例對(duì)象:
 let that;

  /**
   * 原型對(duì)象的 this 指向問題
   * @param name
   * @param age
   * @constructor
   */
  function Star(name, age) {

    this.name = name;
    this.age = age;
    console.log("創(chuàng)建實(shí)例對(duì)象" + that === this);
  }


  Star.prototype.sing = function () {
    // 這里的this指向的是誰? 指向的是函數(shù)的調(diào)用者 當(dāng)前的實(shí)例對(duì)象
    console.log('我會(huì)唱歌');
    console.log(this);
    console.log("創(chuàng)建實(shí)例對(duì)象" + that === this);
    that = this;
  }

  let star = new Star('張三', 23);
  console.log(star);
  star.sing();
  // 1. 在構(gòu)造函數(shù)中,里面this指向的是對(duì)象實(shí)例

  // 2. 原型對(duì)象函數(shù)里面的this指向的是函數(shù)的調(diào)用者,但
  // 是不管是構(gòu)造函數(shù)中的this還是原型對(duì)象中的this都是指向的實(shí)例對(duì)象

1.11 通過原型為數(shù)組擴(kuò)展內(nèi)置方法

console.log(Array.prototype); // 打印Array構(gòu)造函數(shù)中的原型對(duì)象

  /**
   * 擴(kuò)展求和函數(shù)
   */
  Array.prototype.sum = function () {
    let sum = 0;
    for (let i = 0; i < this.length; i++) {
      sum += this[i];
    }
    return sum;
  };

  let arr = [100, 200, 300, 400, 500];
  console.log(arr.sum());

  /**
   * 錯(cuò)誤的追加方式
   */
  Array.prototype = function () {
    let sum = 0;
    for (let i = 0; i < this.length; i++) {
      sum += this[i];
    }
    return sum;
  };

  // 注意:在數(shù)組和字符串內(nèi)置對(duì)象中不能給原型對(duì)象覆蓋操作 Array.prototype = {} 只能是采取 Array.prototype.函數(shù)或者屬性名 = function(){} 的方式

2. 繼承

2.1 call()

  1. call() 可以調(diào)用函數(shù);

  2. call() 可以修改 this 的指向,使用call() 的時(shí)候 參數(shù)一是修改后的 this 指向,參數(shù)2,參數(shù)3..使用逗號(hào)隔開連接。

  // 1.call() 可以調(diào)用函數(shù)
  function fn(x, y) {
    console.log('call()可以調(diào)用函數(shù)和改變函數(shù)的this指向');
    console.log(this);
    console.log(x + y);
  }

  // fn.call();
  let o = {
    name: 'andy'
  }
  // 2.call() 可以改變函數(shù)的this的指向
  fn.call(o, 1, 2);

2.2 子構(gòu)造函數(shù)繼承父構(gòu)造函數(shù)中的屬性

  1. 先定義一個(gè)父構(gòu)造函數(shù);

  2. 再定義一個(gè)子構(gòu)造函數(shù);

  3. 子構(gòu)造函數(shù)繼承父構(gòu)造函數(shù)的屬性(使用call方法)。

 /**
   * 1. 父構(gòu)造函數(shù)
   * @param name
   * @param age
   * @constructor
   */
  function Father(name, age) {
    this.name = name;
    this.age = age;
  }

  /**
   * 2. 子構(gòu)造函數(shù)
   * @param name
   * @param age
   * @constructor
   */
  function Son(name, age) {
    /**
     * 這里的意思是將子構(gòu)造函數(shù)的this、指向了父構(gòu)造函數(shù)的this
     */
    Father.call(this, name, age);

  }

  let son = new Son('李四', 24);
  console.log(son);

2.3 借用原型對(duì)象繼承方法

  1. 先定義一個(gè)父構(gòu)造函數(shù);

  2. 再定義一個(gè)子構(gòu)造函數(shù);

  3. 子構(gòu)造函數(shù)繼承父構(gòu)造函數(shù)的方法(使用 call 方法)。

  /**
   * 1. 父構(gòu)造函數(shù)
   * @param name
   * @param age
   * @constructor
   */
  function Father(name, age) {
    this.name = name;
    this.age = age;
  }

  /**
   *
   * 在父類的原型對(duì)象中添加一個(gè)共享方法
   * */
  Father.prototype.money = function () {
    console.log('100000');
  }

  /**
   * 2. 子構(gòu)造函數(shù)
   * @param name
   * @param age
   * @constructor
   */
  function Son(name, age) {
    /**
     * 這里的意思是將子構(gòu)造函數(shù)的this、指向了父構(gòu)造函數(shù)的this
     */
    Father.call(this, name, age);
  }

  // 如果使用Son的原型對(duì)象 直接指向 Father的原型對(duì)象將會(huì)出現(xiàn)問題
  // Son.prototype = Father.prototype;
  // 讓Son的原型對(duì)象指向 Father 的實(shí)例對(duì)象
  Son.prototype = new Father();

  /**
   * 此時(shí)再Son構(gòu)造函數(shù)中添加一個(gè)方法
   * @type {Son}
   */
  Son.prototype.exam = function () {
    console.log('我要考試');
  }

  let son = new Son('李四', 24);
  console.log(son);

  let father = new Father();
  console.log(father);

如上代碼結(jié)果如圖:

如上代碼結(jié)果

3. ES5新增方法

3.1 數(shù)組方法forEach遍歷數(shù)組

 arr.forEach(function(value, index, array) {
       //參數(shù)一是:數(shù)組元素
       //參數(shù)二是:數(shù)組元素的索引
       //參數(shù)三是:當(dāng)前的數(shù)組
 })
  //相當(dāng)于數(shù)組遍歷的 for循環(huán) 沒有返回值
演示案例 :
  /**
   * 數(shù)組方法 foreach,遍歷數(shù)組的值,并求所有值的和
   */
  let arr = [1, 2, 3, 4, 5, 6, 6, 7, 8, 90];
  let sum = 0;
  arr.forEach((value, index, array) => {
    console.log('每一個(gè)數(shù)組元素' + value);
    console.log('每一個(gè)數(shù)組元素的索引' + index);
    console.log('數(shù)組本身' + array);
    sum += value;
  });

  console.log(sum);

3.2 數(shù)組方法filter過濾數(shù)組

var arr = [12, 66, 4, 88, 3, 7];
  var newArr = arr.filter(function(value, index,array) {
     //參數(shù)一是:數(shù)組元素
     //參數(shù)二是:數(shù)組元素的索引
     //參數(shù)三是:當(dāng)前的數(shù)組
     return value >= 20;
  });
  console.log(newArr);//[66,88] //返回值是一個(gè)新數(shù)組

3.3 數(shù)組方法some

some 查找數(shù)組中是否有滿足條件的元素 
 var arr = [10, 30, 4];
 var flag = arr.some(function(value,index,array) {
    //參數(shù)一是:數(shù)組元素
     //參數(shù)二是:數(shù)組元素的索引
     //參數(shù)三是:當(dāng)前的數(shù)組
     return value < 3;
  });
console.log(flag);//false返回值是布爾值,只要查找到滿足條件的一個(gè)元素就立馬終止循環(huán)

3.4 案例 : 篩選商品案例

ES5數(shù)組新增方法實(shí)現(xiàn)商品查詢
頁面結(jié)構(gòu)
<div class="search">
  按照價(jià)格查詢: <input type="text" class="start"> - <input type="text" class="end">
  <button class="search-price">搜索</button>
  按照商品名稱查詢: <input type="text" class="product">
  <button class="search-pro">查詢</button>
</div>
<table>
  <thead>
  <tr>
    <th>id</th>
    <th>產(chǎn)品名稱</th>
    <th>價(jià)格</th>
  </tr>
  </thead>
  <tbody>
  </tbody>
</table>
頁面樣式
table {
      width: 400px;
      border: 1px solid #000;
      border-collapse: collapse;
      margin: 0 auto;
    }

    td,
    th {
      border: 1px solid #000;
      text-align: center;
    }

    input {
      width: 50px;
    }

    .search {
      width: 600px;
      margin: 20px auto;
    }
自定義數(shù)據(jù)
 // 利用新增數(shù)組方法操作數(shù)據(jù)
  let data = [{
    id: 1,
    pname: '小米',
    price: 3999
  }, {
    id: 2,
    pname: 'oppo',
    price: 999
  }, {
    id: 3,
    pname: '榮耀',
    price: 1299
  }, {
    id: 4,
    pname: '華為',
    price: 1999
  }, {
    id: 5,
    pname: '華為p40',
    price: 6999
  }, {
    id: 6,
    pname: '華為',
    price: 1999
  }];
操作邏輯

// 1. 獲取相應(yīng)的元素
  let tbody = document.querySelector('tbody');
  setData(data);

  function setData(myData) {

    // 先清空原來的數(shù)據(jù)
    tbody.innerHTML = '';

    // 2. 將數(shù)據(jù)渲染到頁面中
    myData.forEach((value) => {
      // 創(chuàng)建行元素
      let tr = document.createElement('tr');
      tr.innerHTML = '<td>' + value.id + '</td><td>' + value.pname + '</td><td>' + value.price + '</td>';
      tbody.appendChild(tr);
    });
  }


  // 3. 根據(jù)價(jià)格查詢商品
  // 搜索按鈕
  let search_price = document.querySelector('.search-price');
  // 開始輸入框
  let start = document.querySelector('.start');
  // 結(jié)束輸入框
  let end = document.querySelector('.end');
  search_price.addEventListener('click', () => {
    let newData = data.filter((value) => {
      return value.price >= start.value && value.price <= end.value;
    });
    setData(newData);
  });

  // 4. 根據(jù)商品名稱查找商品

  // 如果查詢的是數(shù)組中唯一的元素,用some方法更加合適,因?yàn)樗业竭@個(gè)元素就不再進(jìn)行循環(huán)效率更高

  let product = document.querySelector('.product');
  let search_pro = document.querySelector('.search-pro');
  search_pro.addEventListener('click', () => {
    let arr = [];
    data.some((value) => {
      /**
       * 找到之后就會(huì)終止循環(huán)
       */
      if (value.pname === product.value) {
        console.log(value);// 可以實(shí)現(xiàn)打印
        arr.push(value);
        return true; //
      }
    })

    // 將拿到的數(shù)據(jù)渲染到頁面中
    setData(arr);
  });

3.5 some和forEach區(qū)別

  1. 如果查詢數(shù)組中唯一的元素, 用some方法更合適,在some 里面 遇到return true 就是終止遍歷 迭代效率更高。

  2. forEach里面 return不會(huì)終止迭代。

let arr = ['red', 'green', 'blue', 'pink'];
  // 在forEach中return不會(huì)終止循環(huán)

  /**
   * value 滿足條件的值
   *
   * index 滿足條件的索引
   *
   * array 滿足條件的新數(shù)組
   */
  arr.forEach((value, index, array) => {
    if (value === 'green') {
      console.log(value);
      console.log('元素已經(jīng)找到');
      return true;
    }
    console.log(666);
  });

  // some的效率會(huì)更高因?yàn)樵诘谝淮握业皆刂缶蜁?huì)終止循環(huán)
  arr.some((value, index, array) => {
    if (value === 'green') {
      console.log(value);
      console.log('元素已經(jīng)找到');
      return true;
    }
    console.log(666);
  });

3.6 trim方法去除字符串兩端的空格

  1. trim() 方法清除的是字符串兩端的空格,不清楚中間的空格。
<input type="text">
<button>提交</button>
<div></div>

  /**
   * trim 去除字符串兩端的空白字符
   */
  let input = document.querySelector('input');
  let btn = document.querySelector('button');
  let div = document.querySelector('div');

  btn.addEventListener('click', () => {
    let strInput = input.value.trim();
    // 首先判斷一下文本框的內(nèi)容是否為空
    if (strInput === '') {
      alert('輸入框不能為空!');
    } else {
      // 將文本框的內(nèi)容設(shè)置給 div
      div.innerHTML = strInput;
      console.log(strInput);
    }
  });

3.7 Object.keys() 獲取對(duì)象的屬性名

  1. Object.keys(對(duì)象) 獲取到當(dāng)前對(duì)象中的屬性名 ,返回值是一個(gè)數(shù)組:
 var obj = {
     id: 1,
     pname: '小米',
     price: 1999,
     num: 2000
};
var result = Object.keys(obj)
console.log(result)//[id,pname,price,num]

3.8 Object.defineProperty

/**
   *
   * @type {{id: number, pname: string, price: number}}
   *
   * Object.defineProperty(obj , prop,descriptor)
   *
   * 1. obj 對(duì)象
   *
   * 2. prop 需要設(shè)置的屬性
   *
   * 3. 一個(gè)屬性配置對(duì)象
   *
   *  3.1 value: 設(shè)置屬性的值,默認(rèn)值是undefined
   *
   *  3.2 writable: 是否可以被重寫
   *
   *  3.3 enumerable:目標(biāo)屬性是否可以被枚舉。 true | false 默認(rèn)false
   *
   *  3.4 configurable:目標(biāo)屬性是否可以被刪除或是否可以在此修改 true | false 默認(rèn)是false
   */
  let obj = {
    id: 1,
    pname: '小米',
    price: 36669
  };

  Object.defineProperty(obj, 'num', {
    value: 30000,
    writable: false, // 是否可以被重寫
    enumerable: false // 默認(rèn)值是false
  });

  Object.defineProperty(obj, 'pname', {
    writable: false,// 是否可以被重寫
    configurable: false // 是否可以被刪除 設(shè)置為false時(shí)則不再允許刪除這個(gè)屬性,不允許修改第三個(gè)參數(shù)中的特性
  });
  obj.pname = '華為';
  console.log(obj);
  console.log(Object.keys(obj));

  delete obj.pname  // 刪除 pname 屬性

  console.log(obj);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容