前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原型链

原型链

作者头像
用户3258338
发布2020-03-12 16:18:11
4100
发布2020-03-12 16:18:11
举报

每个实例对象(object)都有一个私有属性(__proto__)指向其构造函数的原型对象(prototype)。该原型对象也有自己的原型对象,层层向上直到一个对象的原型对象为null。根据定义null没有原型,并作为原型链的最后一个环节。

几乎所有JS中的对象都是位于原型链顶端的Object的实例

基于原型链的继承


继承属性

JS对象有一个指向原型对象的链。当试图访问一个对象的属性时,还会搜索该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或者到达原型链的末尾。

tips: 遵循ECMAScript标准,someObject.[[prototype]]符号用于访问someObject的原型,等同于JS的非标准但许多浏览器实现的属性__proto__。

但是不能与构造函数func的prototype属性相混淆。被构造函数创建的实例对象的[[prototype]]指向func的prototype属性。Object.prototype属性表示Object的原型对象。

代码语言:javascript
复制
let f=function(){
  this.a = 1;
  this.b = 2;
}
let o = new f();
//  在f函数的原型上定义属性
f.prototype.b = 3;
f.prototype.c = 4;
// 不要在f的原型上直接定义f.prototype = {b:3,c:4};这样会直接破坏原型链
// o.[[prototype]] 有属性b和c
// (其实这就是o.__proto__ 或者 o.constructor.prototype)
// o.[[prototype]].[[prototype]]是Object.prototype
// 最后o.[[prototype]].[[prototype]].[[prototype]]是null
// 这就是原型链的末尾,即null
// 根据定义,null就是没有[[prototype]]

// 综上,这个原型链如下:
// {a:1, b:2}--->{b:3, c:4}---> Object.prototype ---> null

console.log(o.a); // 1
// a是o的自身属性吗?是的,该属性的值是1

console.log(o.b); // 2
// b是o的自身属性吗?是的,该属性值为2
// 原型上也有一个‘b’属性,但是它不会被访问到
// 这种情况叫做“属性遮蔽”

console.log(o.c) // 4
// c是o的自身属性吗?不是,那看看它的原型上有没有
// c是o.[[prototype]]的属性吗?是,该属性值为4

console.log(o.d) // undefined
// d是o的自身属性吗?不是,那看看它的原型上有没有
// d是o.[[prototype]]的属性吗?不是,那看看他的原型上有没有
// o.[[prototype]].[[prototype]]为null,停止搜索
// 找不到d属性返回undefined

使用不同的方法来创建对象和生成原型链


(1)使用语法结构创建的对象

代码语言:javascript
复制
var o = {a: 1};
//  o这个对象继承了Object.prototype上面的所有属性
// Object.prototype的原型为null
// 原型链如下
// o -->Object.prototype -->null

var a = ["yo", "dkdkk", "dkl"];
// 数组都继承自 Array.prototype
// 原型链如下
// a --> Array.prototype --> Object.prototype --> null

function f(){
  return 2;
}
// 函数都继承自Function.prototype
// 原型链如下
// f --> Function.prototype --> Object.prototype --> null

(2)使用构造器创建的对象

在JS中,构造器其实就是一个普通的函数,当使用new 操作符来调用这个函数时,他就可以被称为构造方法(构造函数)。

代码语言:javascript
复制
function Graph(){
  this.vertices = [];  
  this.edges = [];
}
Graph.prototype = {
  addVertex:function(v){
    this.vertices.push(v)
  }
}
var g = new Graph();
// g是生成的对象,他的自身属性有‘vertices’和edges
// 在g被实例化时,g.[[prototype]]指向了Graph.prototype

(3)使用Object.create创建的对象

可以调用Object.create()创建一个对象,新对象的原型就是传入的第一个参数。

代码语言:javascript
复制
var a = {a:1};
// a --> Object.prototype --> null
var b = Object.create(a);
// b --> a --> Object.prototype --> null
var c = Object.create(b)
// c --> b --> a -->Object.prototype --> null
var d = Object.create(null);
// d --> null
console.log(d.hasOwnProperty); 
// undefined ,因为d没有继承Object.prototype

(4)使用Class关键字创建的对象

代码语言:javascript
复制
class Polugon{
  constructor(height, width){
    this.height = height;
    this.width = width;
  }
}
class Square extends Polygon{
  constructor(sideLength){
    super(sideLength, sideLength)
  }
  get area(){
    return this.height * this.width
  }
  set sideLength(newLength){
    this.height = newLength;
    this.width = newLength;
  }
}
var square = new Square()

每张故作坚强的笑脸背后,是怎样风雨漂泊的一生---Lin

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 女程序员的日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档