1. 程式人生 > >JavaScript 原型學習 拓展toString 精度計算

JavaScript 原型學習 拓展toString 精度計算

  • 定義

        原型是function物件的一個屬性,它定義了建構函式製造出來的物件的公共祖先。通過該建構函式產生的物件,可以繼承該原型的屬性和方法。原型也是物件。

  • 利用原型特點和概念,可以提取共有屬性。
  • 物件如何檢視原型 --> 隱式屬性 __proto__
  • 物件如何檢視物件的建構函式  --> constructor

//Person.prototype --> 原型  
//Person.prototype = {} 是祖先
Person.prototype.name = 'xiaoming'
function Person() {
    // constructor: Person // 預設 可修改
}

var person = new Person();
person.name; // 'xiaoming'

var person1 = new Person();
person1.name; // 'xiaoming'

person.constructor; // 輸出 Person(){}


// constructor 可設定構造物件的構造器 可用來找爹
function Car() {}
Car.prototype = {
    constructor: Car
}
function Car2() {}
var car = new Car2();
car.constructor; // 輸出 function Car(){}  // car來自 function Car(){}


// __proto__ 存的是該物件的原型
Person3.prototype.name = 'abc';
function Person3() {
    // var this = {
        // __proto__: Person3.prototype
    // }
}

var obj = {
    name: 'sunny'
}
var person3 = new Person3();
person3.name; // 輸出 'abc'

person3.__proto__ = obj;
person3.name; // 輸出 'sunny'

  • 原型練習
Person.prototype.name = 'sunny';

function Person() {

}

person.prototype.name = 'cherry';

var person = new Person();

// person.prototype.name = 'cherry'; // 寫在new的後面也一樣打印出cherry 因為改的是屬性

console.log(person.name); // 'cherry';



Person2.prototype.name = 'sunny';

function Person2() { }

Person2.prototype = {
    name: 'cherry'
}

var person2 = new Person2();

// Person2.prototype = {  // 如果在new的後面改prototype 無效,物件已經new出來了
//    name: 'apple'
// }

console.log(person2.name); // 'cherry' 執行順序,new的時候 prototype 已經被改變
  • 原型鏈

        絕大多數物件的最終都會繼承自Object.prototype

        Object.create(原型)

  • 原型鏈練習
// 原型鏈的連結就是 __proto__
// 原型鏈的終端就是Object.prototype
// Grand.prototype.__proto__ ==> Object.prototype

Grand.prototype.lastName = 'wang';

function Grand() {}

var grand = new Grand();

Father.prototype = grand;

function Father() {
    this.name = 'xiaoming',
    this.fortune = {
        card1: 'visa'
    },
    this.num = 100
}

var father = new Father();

Son.prototype = father;

function Son() {
    this.hobbit = 'smoke'
}

var son = new Son();

console.log(son.hobbit); // 'smoke'
console.log(son.name); // 'xiaoming'
console.log(son.lastName); // 'wang'

son.fortune.card2 = 'master'; // 操作的是父級的fortune
console.log(father.fortune); // { card1: 'visa', card2: 'master'}

son.num ++; // son.num = son.num + 1; // son.num => 101; 未改變父級的num
console.log(father.num); // 100;
console.log(son.num); // 101;
  • 練習2
Person.prototype = {
    name: 'a',
    sayName: function () {
        console.log(this.name);
    },
    height = 100;
}

function Person() {
    this.name = 'b';
    this.eat = function () {
        this.height ++;
    }
}

var person = new Person();

console.log(person.sayName()); // 輸出 ‘b’ 因為是Person呼叫的

console.log(person.prototype.sayName()); // 輸出 ‘a’

person.eat();
console.log(person.height); // 101
console.log(person.height); // 100
  • Object.create(原型 / null)
var obj = Object.create(null);
console.log(obj.prototype); // 空的,因為null 沒有prototype
// 即使手動給他賦值 prototype 也無法繼承 因為不是系統自動生成的

Person.prototype = {
    name: 'a'
} 
function Person() { }

var person = new Person();

// 以上程式碼可以寫成  var person = Object.create({name: 'a'});
  • 拓展 toString()
// 123.toString(); // 報錯,因為這個點會被系統識別為小數點

// 正確要寫成 
var num = 123;
num.toString();
// 數字 toString() 會呼叫包裝類 new Number(num)
// Number 有toString方法 重寫了 Object.toString
// Number.prototype.toString = function() {}
// Number.prototype.__proto__ ==> Object()

// 重寫了 Object.toString()
// Array.prototype.toString
// Booblean.prototype.toString
// String.prototype.toString

// 我們可以根據情況重寫toString方法
Number.prototype.toString = function() {
    return 321;
}
var num1 = 123;
num1.toString(); // 輸出321
  • 拓展 JavaScript精度計算

        可正常計算的範圍 小數點前16位和後16位

var num = 0.14;
console.log(num * 100); // 輸出 14.000000000000002