原型操作小结

270 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

原型的目的是提高复用,没错吧! 那有哪些属性和方法是和操作原型有关的呢? 今天我们就一起来学习吧。

列出了8种方式,您还有其他方式吗? 欢迎补充。

基础准备

学习之前,需要知道一点点基本知识:

  1. function 有 prototype__proto__
function a() {};
console.log("prototype:", a.prototype);  // prototype: {constructor: ƒ}
console.log("__proto__", a.__proto__);   // __proto__ ƒ () { [native code] }
  1. object 有 __proto__
var a = {};
console.log("prototype:", a.prototype);  // prototype: undefined
console.log("__proto__", a.__proto__);   // __proto__ {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

这里是不是从侧面验证了,function 也是 object呢?

prototype

FunctionFunction实例均有此属性。 当你编程突然不知道有没有某些方法的时候,不妨控制台打印一些, 比如:

截图_20215426095416.png

__proto__

其为构造函数的prototype, 来看一个栗子:

var arr = [];
console.log("constructor:", arr.constructor.name);   // Array
console.log("eq:", arr.__proto__ === Array.prototype); // true

instanceof

经常用来判断数据类型, 其原理就是原型链上查找。

[] instanceof Array  // true 

Object.setPrototypeOf

设置某个对象的原型,其可以用来替代 __proto__

function Animal(){
}

function Person(){
}

Object.setPrototype(Person, new Animal());

Reflect.setPrototypeOf

Reflect.setPrototypeOf和Object.setPrototypeOf功能一致,只是调用的参数不太一样。

Object.getPrototypeOf

获取对象的原型,如果传入 null, undefined会报错。

一起看看8种基础数据类型的情况:

Object.getPrototypeOf(null) // VM7671:1 Uncaught TypeError: Cannot convert undefined or null to object
Object.getPrototypeOf(undefined) // VM7773:1 Uncaught TypeError: Cannot convert undefined or null to object
Object.getPrototypeOf(1)  // Number
Object.getPrototypeOf("")  // String
Object.getPrototypeOf(true) // Boolean
Object.getPrototypeOf(function(){}) //  ƒ () { [native code] }
Object.getPrototypeOf(10n)  // BigInt
Object.getPrototypeOf(Symbol.for("s")) // Symbol

Reflect.getPrototypeOf

Reflect.getPrototypeOf和Object.getPrototypeOf功能一样,只是调用的参数不一样。

Object.isPrototypeOf

和instanceof 相反,其判断是不是别人的原型。 其不会抛出异常,相对而言比较安全。

Object.prototype.isPrototypeOf({})  // true
Object.prototype.isPrototypeOf(window) // true
Object.prototype.isPrototypeOf(null) // false
Object.prototype.isPrototypeOf(function(){}) // true

上面也验证了Object.prototype在普通函数的原型链上。

小结

8种形式的操作,那你可能要问,我应该使用哪一样呢? 应该是优先使用高级语法的,尤其别直接使用 __proto__这种非官方暴露的属性。
今天你收获了吗?