导图社区 javaScript原型链
一张思维导图带你学习javaScript原型链的知识点,包含概念、prototype的关系、继承控制、构造constructor等内容。
编辑于2021-09-20 03:54:15javaScript原型链
概念
JavaScript之继承(原型链)
数据结构
var Person = function(){}; Person.prototype.type = 'Person'; Person.prototype.maxAge = 100;
prototype(原型)
constructor(构造方法)
Person.prototype.constructor === Person;
自己的构造,指向自己. 无限循环
__proto__(原型链)
Person.prototype.__proto__ === Object.prototype
指向Object对象prototype(原型)
__proto__(原型链/遗传进化链)
第一层指向,Function对象prototype(原型)
Person.__proto__ === Function.prototype
同时Function对象的__proto__(原型链)也指向Function的prototype(原型)
Function.__proto__ === Function.prototype
第二层指向,Object对象prototype(原型)
Person.__proto__.__proto__ === Object.prototype
第三次指向,null
Person.__proto__.__proto__.__proto__ === null
var p = new Person(); console.log(p.maxAge); p.name = 'rainy';
实例对象没有prototype原型属性
仅具有__proto__(原型链)
第一层指向,Person对象prototype(原型)
new Person().__proto__ === Person.prototype
第二层指向,Object对象prototype(原型)
new Person().__proto__.__proto__ == Object.prototype
第二层指向,还等同Person对象的第二层指向
new Person().__proto__.__proto__ === Person.__proto__.__proto__
第三次指向,null
new Person().__proto__.__proto__.__proto__ === null
prototype、__proto__的关系
dir(Array)
dir(new Array())
new Array().__proto__ === Array.prototype
true
Array.prototype
Array.
可访问form直接方法
也可访问Array.__proto__内方法
也可访问Array.__proto__.__proto__.... 内方法[继承]
检验是否非进化链__proto__继承的属性
.hasOwnProperty("")
构造指向自己
Array.prototype.constructor === Array
true
Array.prototype.constructor.prototype.constructor.prototype.constructor ....
function Array() { [native code] }
__proto__
遗传进化链 or 进化链指针
进化链指针
new String().__proto__ === String.prototype
JS内置构造器和自定义函数都是Function构造器的原型(prototype)
Array.__proto__ === Function.prototype
true
String.__proto__ === Function.prototype
true
Function.__proto__ === Function.prototype
true
只有Function.prototype是函数(function)类型
为了保证函数构造器们的__proto__指向的都是函数
不能new的目标
没有构造函数(不是函数),不能new
function才有构造,object没有
继承控制
Object
Object.setPrototypeOf(child, parent);
(function () { 'use strict'; var parent = { foo() { console.log("Hello from the Parent"); } } var child = { foo() { super.foo(); console.log("Hello from the Child"); } } Object.setPrototypeOf(child, parent); child.foo(); // Hello from the Parent // Hello from the Child })();
Object.prototype.extend
class
class Porsche extends Car
(function () { 'use strict'; class Car { constructor() { console.log("Creating a new car"); } } class Porsche extends Car { constructor() { super(); console.log("Creating Porsche"); } } let c = new Porsche(); })();
function
inherits(Chinese, People) & People.call(this, name, age)
function inherits(child, parent) { var _proptotype = Object.create(parent.prototype); _proptotype.constructor = child.prototype.constructor; child.prototype = _proptotype; } function People(name, age) { this.name = name; this.age = age; } People.prototype.getName = function () { return this.name; } function English(name, age, language) { People.call(this, name, age); this.language = language; } inherits(English, People); English.prototype.introduce = function () { console.log('Hi, I am ' + this.getName()); console.log('I speak ' + this.language); } function Chinese(name, age, language) { People.call(this, name, age); this.language = language; } inherits(Chinese, People); Chinese.prototype.introduce = function () { console.log('你好,我是' + this.getName()); console.log('我说' + this.language); } var en = new English('Byron', 26, 'English'); var cn = new Chinese('色拉油', 27, '汉语'); en.introduce(); cn.introduce();
inherits(Chinese, People)
function inherits(child, parent) { var _proptotype = Object.create(parent.prototype); _proptotype.constructor = child.prototype.constructor; child.prototype = _proptotype; } function People(name, age) { this.name = name; this.age = age; console.log('people.'); } People.prototype.getName = function () { return this.name; } function English(name, age, language) { People.call(this, name, age); this.language = language; console.log('English.'); } // inherits(English, People); dir(English)
作用
child.prototype = Object.create(parent.prototype)
通过prototype的覆盖获得parent所有的数据结构
注意,覆盖会造成自身数据结构的丢失
如需自定义数据结构需要在inherits()后赋予
function English(name, age, language) { People.call(this, name, age); this.language = language; } inherits(English, People); // 需要在inherits其后进行,负责会被覆盖性丢失 English.prototype.introduce = function () { console.log('Hi, I am ' + this.getName()); console.log('I speak ' + this.language); }
People.call(this, name, age)
function inherits(child, parent) { var _proptotype = Object.create(parent.prototype); _proptotype.constructor = child.prototype.constructor; child.prototype = _proptotype; } function People(name, age) { this.name = name; this.age = age; console.log('people.'); } People.prototype.getName = function () { return this.name; } function English(name, age, language) { // People.call(this, name, age); this.language = language; console.log('English.'); }
作用
调用call,使用当前this(English)执行People函数
构造 Constructor
声明对象
function Prince(name, age) { // [new obj()] 函数内部可以使用this关键字在构造函数内部,this指向的是构造出的新对象 this.gender = "male"; this.kind = true; this.rich = true; this.name = name; this.age = age; } // 通过原型链-增加函数方法 Prince.prototype.toFrog = function () { console.log("Prince " + this.name + " turned into a frog."); }; var prince = new Prince("charming", 25);// 构造函数Prince()中的this指向新创建的对象prince prince.toFrog();//Prince charming turned into a frog. console.log(prince); console.log(prince.kind);//true console.log(prince.age);// 25 - 实例才能访问到 console.log(Prince.age);// undefined - 不能用类型名访问
实例对象
class Person { /* 默认方法,通过new命令生成对象实例时,自动调用该方法 */ constructor(name, age, job) { this.name = name; this.age = age; this.job = job; } sayName() { console.log(this.name); } } var friend = new Person("Nicholas", 29, "Software Engineer"); friend.sayName();// Nicholas console.log(friend.age);// 29
javaScript原型链图解
new Object()
*
__proto__
not __proto__
Object
*
prototype
not __proto__
__proto__
__proto__
Object原型
prototype
not __proto__
Function
*
prototype
constructor
__proto__
__proto__
Function.__proto__ === Function.prototype
__proto__
Person
*
prototype
constructor
...
_proto__
证明指向: Function.prototype.__proto__.debug = true; Person.prototype.__proto__
not __proto__
__proto__
__proto__
not __proto__
new Person()
*
not prototype
__proto__
new Person().__proto__ === Person.prototype new Person().__proto__.__proto__ === Object.prototype new Person().__proto__.__proto__.__proto__ == null
__proto__
not __proto__
javaScript自定义继承图解
function inherits(child, parent) { var _proptotype = Object.create(parent.prototype); _proptotype.constructor = child.prototype.constructor; child.prototype = _proptotype; } function People(name, age) { this.name = name; this.age = age; } People.prototype.getName = function () { return this.name; } function English(name, age, language) { People.call(this, name, age); this.language = language; } inherits(English, People); English.prototype.introduce = function () { console.log('Hi, I am ' + this.getName()); console.log('I speak ' + this.language); } function Chinese(name, age, language) { People.call(this, name, age); this.language = language; } function inherits(child, parent) { var _proptotype = Object.create(parent.prototype); _proptotype.constructor = child.prototype.constructor; child.prototype = _proptotype; } inherits(Chinese, People); Chinese.prototype.introduce = function () { console.log('你好,我是' + this.getName()); console.log('我说' + this.language); } var en = new English('Byron', 26, 'English'); var cn = new Chinese('色拉油', 27, '汉语'); en.introduce(); cn.introduce();
new English()
__proto__ === Chinese.prototype
new Chinese().__proto__ === Chinese.prototype new Chinese().__proto__.__proto__ === People.prototype new Chinese().__proto__.__proto__.__proto__ === Object.prototype new Chinese().__proto__.__proto__.__proto__.__proto__ === null
__proto__ === People.prototype
__proto__ === Object.prototype
not __proto__
constructor function(){}
People.call(this, name, age);
English
prototype
__proto__ === new People().__proto__ === People.prototype
function inherits(child, parent) { var _proptotype = Object.create(parent.prototype); _proptotype.constructor = child.prototype.constructor; child.prototype = _proptotype; } inherits(Chinese, People);
__proto__ === Object.prototype
not __proto__
constructor
language (完成覆盖继承后再添加自有属性,否则就覆盖了)
__proto__ === Function.prototype (未受prototype赋值的继承影响)
__proto__ === Object.prototype
not __proto__
new People()
Object.create(People.prototype);
__proto__
Function
*
prototype
constructor
__proto__
__proto__
Function.__proto__ === Function.prototype
__proto__
Object原型
prototype
not __proto__
new Chinese()
__proto__ === Chinese.prototype
new Chinese().__proto__ === Chinese.prototype new Chinese().__proto__.__proto__ === People.prototype new Chinese().__proto__.__proto__.__proto__ === Object.prototype new Chinese().__proto__.__proto__.__proto__.__proto__ === null
__proto__ === People.prototype
__proto__ === Object.prototype
not __proto__
constructor function(){}
People.call(this, name, age);
Chinese
prototype
__proto__ === new People().__proto__ === People.prototype
function inherits(child, parent) { var _proptotype = Object.create(parent.prototype); _proptotype.constructor = child.prototype.constructor; child.prototype = _proptotype; } inherits(Chinese, People);
__proto__ === Object.prototype
not __proto__
constructor
language (完成覆盖继承后再添加自有属性,否则就覆盖了)
__proto__ === Function.prototype (未受prototype赋值的继承影响)
__proto__ === Object.prototype
not __proto__
People
prototype
name
age
getName
constructor
__proto__ === Function.prototype.__proto__ === Object.prototype
__proto__ === Function.prototype
__proto__ === Object.prototype
not __proto__