JS原型与继承的秘密浏览器
1、protoapp
除null和undefined,JS中的全部数据类型都有这个属性; 它表示当咱们访问一个对象的某个属性时,若是该对象自身不存在该属性, 就从它的__proto__属性上继续查找,以此类推,直到找到,若找到最后仍是没有找到,则结果为undefined函数
咱们把一个对象的__proto__属性所指向的对象叫该对象的原型;咱们能够修改一个对象的原型来让这个对象拥有某种属性或某个方法性能
// 修改一个Number类型的值的原型spa
const num = 1;prototype
num.__proto__.name = "My name is 1";code
console.log(num.name); // My name is 1对象
// 修改一个对象的原型继承
const obj = {};ip
obj.__proto__.name = "dreamapple";
console.log(obj.name); // dreamapple
需注意的是,__proto__属性虽多数浏览器支持,但其实它仅在ECMAScript 2015规范中才被准肯定义, 目的是为了给这个传统的功能定制一个标准,以确保浏览器间的兼容性。经过使用__proto__属性来修改一个对象的原型很是慢且影响性能。 因此,若想获取一个对象的原型,推荐用Object.getPrototypeOf 或Reflect.getPrototypeOf,设置一个对象的原型推荐用Object.setPrototypeOf或Reflect.setPrototypeOf
2、prototype
首先要记住的是,该属性通常只存在于函数对象上; 只要是能做为构造器的函数,都包含这个属性。即只要这个函数能经过new生成一个新对象, 那么这个函数确定具备prototype属性。由于咱们自定义的函数均可经过new生成一个对象,因此咱们自定义的函数都有prototype 这个属性
// 函数字面量
console.log((function(){}).prototype); // {constructor: ƒ}
// Date构造器
console.log(Date.prototype); // {constructor: ƒ, toString: ƒ, toDateString: ƒ, toTimeString: ƒ, toISOString: ƒ, …}
// Math.abs 不是构造器,不能经过new操做符生成一个新的对象,因此不含有prototype属性
console.log(Math.abs.prototype); // undefined
prototype属性有什么做用呢?做用就是:函数经过new生成的一个对象, 这个对象的原型(__proto__)指向该函数的prototype属性:
// 其中F表示一个自定义的函数或者是含有prototype属性的内置函数
new F().__proto__ === F.prototype // true
// 经过函数字面量定义的函数的__proto__属性都指向Function.prototype
(function(){}).__proto__ === Function.prototype // true
// 经过对象字面量定义的对象的__proto__属性都是指向Object.prototype
({}).__proto__ === Object.prototype // true
// Object函数的原型的__proto__属性指向null
Object.prototype.__proto__ === null // true
// 由于Function自己也是一个函数,因此Function函数的__proto__属性指向它自身的prototype
Function.__proto__ === Function.prototype // true
// 由于Function的prototype是一个对象,因此Function.prototype的__proto__属性指向Object.prototype
Function.prototype.__proto__ === Object.prototype // true
3、constructor无锡看男科医院哪家好 https://yyk.familydoctor.com.cn/20612/
constructor表示一个对象的构造函数,除null和undefined,JS中的全部数据类型都有这个属性; 咱们可经过下面的代码来验证一下:
null.constructor // Uncaught TypeError: Cannot read property 'constructor' of null ...
undefined.constructor // Uncaught TypeError: Cannot read property 'constructor' of undefined ...
(true).constructor // ƒ Boolean() { [native code] }
(1).constructor // ƒ Number() { [native code] }
"hello".constructor // ƒ String() { [native code] }
一个对象的constructor属性确切地说并非存在这个对象上面的; 而是存在这个对象的原型上(若是是多级继承需手动修改原型的constructor属性),咱们可用下面的代码来解释一下:
const F = function() {};
// 当咱们定义一个函数的时候,这个函数的prototype属性上面的constructor属性指向本身自己
F.prototype.constructor === F; // true
对JS的原始类型(string, number, boolean, null, undefined, symbol (new in ECMAScript 2015)),它们的constructor属性是只读的,不可修改:
(1).constructor = "something";
console.log((1).constructor); // 输出 ƒ Number() { [native code] }
若是真想改这些原始类型的constructor属性,也不是不能够:
Number.prototype.constructor = "number constructor";
(1).constructor = 1;
console.log((1).constructor); // 输出 number constructor
固然上面的方式不推荐