原型链

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

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

基于原型链的继承


继承属性

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

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

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

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)使用语法结构创建的对象

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 操作符来调用这个函数时,他就可以被称为构造方法(构造函数)。

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()创建一个对象,新对象的原型就是传入的第一个参数。

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关键字创建的对象

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

本文分享自微信公众号 - 女程序员的日常(gh_df41d619fb70),作者:凛

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JS实现继承的方式

    构造函数继承的关键:在Child构造函数中执行Parent.call(this)。

    用户3258338
  • V8引擎对Array.prototype.push的源码实现

    一直非常困惑操作arguments的时候为什么都要用Array.prototype,今天终于明白了。

    用户3258338
  • Iterator 、Generator

    JS里原有的表示”集合“的数据结构,主要是Array和Object,ES6又添加了Map和Set。我们可以任意组合和设计数据的结构,那么就需要一个机制,可处理所...

    用户3258338
  • 在Go程序中实现服务器重启的方法

    Go被设计为一种后台语言,它通常也被用于后端程序中。服务端程序是GO语言最常见的软件产品。在这我要解决的问题是:如何干净利落地升级正在运行的服务端程序。 目标:...

    李海彬
  • Ubuntu12.04快速部署 Nginx + MySQL + PHP + Memcached + XCache + phpMyAdmin

    #装好后,配置文件都在/etc/nginx/目录下面,网站目录在/usr/share/nginx/www/下面

    libo1106
  • Python开发GUI程序---tkinter试用

    电脑上文档文件被流氓软件加密,文档打开后乱码,听说通过重命名将文件类型更换为*.js然后再更成原来的文件类型后缀可以实现解密,于是用tkinter写了一...

    MiaoGIS
  • 基于docker搭建jumpserver堡垒机

      1、 192.168.137.129 CentOS6.4 kernel版本为 3.10.5-3.el6.x86_64

    菲宇
  • EasyNVS摄像机公网全终端无插件网页摄像机直播管理服务EasyNVS如何在内网环境下与外网和公网对接

    由于互联网的飞速发展,传统安防摄像头的视频监控直播与互联网直播相结合是大势所趋。传统安防的直播大多在一个局域网内,在播放的客户端上也是有所限制,一般都需要OCX...

    EasyNVR
  • java中final关键字的作用

    被final关键字修饰的类不能被继承,被final关键字修饰的类属性和类方法不能被覆盖(重写);

    用户7886150
  • 集合系列 Set(八):TreeSet

    TreeSet 是 Set 集合的红黑树实现,但其内部并没有具体的逻辑,而是直接使用 TreeMap 对象实现。我们先来看看 TreeSet 的定义。

    陈树义

扫码关注云+社区

领取腾讯云代金券