JS整頓知識點5.10

toString() 的運用:推斷數據範例
為了獲得範例字符串,最好直接運用Object.prototype.toString要領。經由過程函數的call要領,能夠在恣意值上挪用這個要領,協助我們推斷這個值的範例。

**Object.prototype.toString.call(value)**

差別數據範例的Object.prototype.toString要領返回值以下。
數值:返回[object Number]。
字符串:返回[object String]。
布爾值:返回[object Boolean]。
undefined:返回[object Undefined]。
null:返回[object Null]。
數組:返回[object Array]。
arguments 對象:返回[object Arguments]。
函數:返回[object Function]。
Error 對象:返回[object Error]。
Date 對象:返回[object Date]。
RegExp 對象:返回[object RegExp]。
其他對象:返回[object Object]。

能夠寫出一個比typeof運算符更正確的範例推斷函數。

var type = function (o){
  var s = Object.prototype.toString.call(o);
  return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};

type({}); // "object"
type([]); // "array"
type(5); // "number"
type(null); // "null"
type(); // "undefined"
type(/abcd/); // "regex"
type(new Date()); // "date"

new 敕令的道理
運用new敕令時,它背面的函數順次實行下面的步驟。

  1. 建立一個空對象,作為將要返回的對象實例。
  2. 將這個空對象的原型,指向組織函數的prototype屬性。
  3. 將這個空對象賦值給函數內部的this關鍵字。
  4. 最先實行組織函數內部的代碼。

組織函數內部,this指的是一個新天生的空對象,一切針對this的操縱,都邑發作在這個空對象上。組織函數之所以叫“組織函數”,就是說這個函數的目標,就是操縱一個空對象(即this對象),將其“組織”為須要的模樣。

假如組織函數內部有return語句,而且return背面隨着一個對象,new敕令會返回return語句指定的對象;不然,就會不論return語句,返回this對象。

var Vehicle = function () {
  this.price = 1000;
  return 1000;
};

(new Vehicle()) === 1000
// false

上面代碼中,組織函數Vehicle的return語句返回一個數值。這時刻,new敕令就會疏忽這個return語句,返回“組織”后的this對象。

假如return語句返回的是一個跟this無關的新對象,new敕令會返回這個新對象,而不是this對象

var Vehicle = function (){
  this.price = 1000;
  return { price: 2000 };
};

(new Vehicle()).price
// 2000

假如對一般函數(內部沒有this關鍵字的函數)運用new敕令,則會返回一個空對象。

function getMessage() {
  return 'this is a message';
}

var msg = new getMessage();

msg // {}
typeof msg // "object"

函數內部能夠運用new.target屬性。假如當前函數是new敕令挪用,new.target指向當前函數,不然為undefined。

function f() {
  console.log(new.target === f);
}

f() // false
new f() // true

能夠推斷函數挪用的時刻,是不是運用new敕令。

function f() {
  if (!new.target) {
    throw new Error('請運用 new 敕令挪用!');
  }
  // ...
}

f() // Uncaught Error: 請運用 new 敕令挪用!

Object.create() 建立實例對象

偶然拿不到組織函數,只能拿到一個現有的對象。我們願望以這個現有的對象作為模板,天生新的實例對象

var person1 = {
  name: '張三',
  age: 38,
  greeting: function() {
    console.log('Hi! I\'m ' + this.name + '.');
  }
};

var person2 = Object.create(person1);

person2.name // 張三
person2.greeting() // Hi! I'm 張三.

Object.getPrototypeOf()

要領返回參數對象的原型。這是獵取原型對象的規範要領。

var F = function () {};
var f = new F();
Object.getPrototypeOf(f) === F.prototype // true

// 空對象的原型是 Object.prototype
Object.getPrototypeOf({}) === Object.prototype // true

// Object.prototype 的原型是 null
Object.getPrototypeOf(Object.prototype) === null // true

// 函數的原型是 Function.prototype
function f() {}
Object.getPrototypeOf(f) === Function.prototype // true

object.create要領,用來滿足這類需求。該要領接收一個對象作為參數,然後以它為原型,返回一個實例對象。該實例完整繼續原型對象的屬性。

// 原型對象
var A = {
  print: function () {
    console.log('hello');
  }
};

// 實例對象
var B = Object.create(A);

Object.getPrototypeOf(B) === A // true
B.print() // hello
B.print === A.print // true
//以A對象為原型,天生了B對象。B繼續了A的一切屬性和要領。

三種體式格局天生的新對象是等價的。

var obj1 = Object.create({});
var obj2 = Object.create(Object.prototype);
var obj3 = new Object();

假如想要天生一個不繼續任何屬性(比方沒有toString和valueOf要領)的對象,能夠將Object.create的參數設為null

對象obj的原型是null,它就不具備一些定義在Object.prototype對象上面的屬性,比方valueOf要領。

var obj = Object.create(null);

obj.valueOf()
// TypeError: Object [object Object] has no method 'valueOf'

第二個參數:是一個屬性形貌對象,它所形貌的對象屬性,會添加到實例對象,作為該對象本身的屬性。

實例對象的isPrototypeOf要領,用來推斷該對象是不是為參數對象的原型。

Object.prototype.isPrototypeOf({}) // true
Object.prototype.isPrototypeOf([]) // true
Object.prototype.isPrototypeOf(/xyz/) // true
Object.prototype.isPrototypeOf(Object.create(null)) // false

因為Object.prototype處於原型鏈的最頂端,所以對種種實例都返回true,只要直接繼續自null的對象除外。

對象實例的hasOwnProperty要領返回一個布爾值,用於推斷某個屬性定義在對象本身,照樣定義在原型鏈上。

Date.hasOwnProperty('length') // true
Date.hasOwnProperty('toString') // false

對象的拷貝

確保拷貝后的對象,與原對象具有一樣的原型。
確保拷貝后的對象,與原對象具有一樣的實例屬性。

function copyObject(orig) {
  return Object.create(
    Object.getPrototypeOf(orig),
    Object.getOwnPropertyDescriptors(orig)
  );
}
//應用 ES2017 才引入規範的Object.getOwnPropertyDescriptors要領
    原文作者:wanjeong
    原文地址: https://segmentfault.com/a/1190000014816899
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞