先上一段代码和关系图

  1. function Person(){}
  2. Person.prototype.name = "Nic"
  3. Person.prototype.age = 22
  4. Person.prototype.job= "Software Engineer"
  5. Person.prototype.sayName = function(){
  6. alert(this.name)
  7. }
  8. var person1 = new Person();
  9. var person2 = new Person();
  10. alert(person1.sayName == person2.sayName) //true

图1

开始进入正题

无论什么时候,只要创建了一个新的函数,就会根据特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性是一个指向protopype属性所在函数的指针,拿上面的代码来说,Person.prototype.constructor指向Person。通过这个构造函数我们还可以继续为原型对象添加其他属性和方法。

创建自定义的构造函数之后其原型对象只会默认取得constructor属性;至于其他方法都是从Object继承而来的。当调用一个构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型属性ES5中管这个指针叫[[Prototype]]。虽然在脚本中没有标准的方式访问[[Prototype]],但是在Firefox、Safari、Chrome在每个对象上都支持一个属性_proto_;这个连接存在于实例与构造函数的原型对象之间,而不是存在与实例与构造函数之间。图1 就展示了各个对象之间的关系

再来一段代码

  1. function Person(){
  2.  
  3. }
  4. Person.prototype.name = "Nic"
  5. Person.prototype.age= 29
  6.  
  7. var person1 = new Person()
  8. var person2 = new Person()
  9. person1.name = "Greg"
  10. alert(person1.name) //"Greg" 来自实例
  11. alert(person1.name) //"Nic" 来自原型
  12.  
  13. delete person1.name
  14. alert(person1.name) //"Nic" 来自原型

上面这段代码说明了,可以通过对象实例访问到原型里的值,但是不能通过对象实例重写原型的值。如果我们添加了一个属性,而该属性和原型对象的属性重名,我们就在该实例中创建该属性,并且屏蔽原型中的那个属性,可以通过delete删除实例的的属性,从而让我们重新访问原型的属性

我们再再来一段代码

  1. function Person(){
  2.  
  3. }
  4. var friend = new Person()
  5. Person.prototype.sayHi = function(){
  6. alert("Hi")
  7. }
  8. friend.sayHi() //"Hi" (没有问题!)
  9.  
  10. Person.prototype = {
  11. constructor:Person,
  12. name:"Nic",
  13. sayHi:function(){
  14. alert(this.name)
  15. }
  16. }
  17. friend.sayHi() //"Hi" (还是"Hi")

上述代码说明两个问题

1.实例与原型之间的关系是松散的调用firend.sayHi()会先在实例中搜索,没有找到就会去原型中搜索,因为实例和原型之间的连接仅仅是一个指针而不是一个副本,因此可以获得原型中更新后的sayHi属性,

2.如果我们重写整个原型对象那么情况就不一样了。我们知道调用构造函数时会为实例添加一个指向最初原型的指针[[Prototype]],而把原型修改为另一个对象就等于切断了构造函数与最初原型之间的联系

看图

重写原型对象之前

图2

重写原型对象之后

图3

Javascript高级程序设计--读书笔记之理解原型对象的更多相关文章

  1. Javascript高级程序设计读书笔记(第六章)

    第6章  面向对象的程序设计 6.2 创建对象 创建某个类的实例,必须使用new操作符调用构造函数会经历以下四个步骤: 创建一个新对象: 将构造函数的作用域赋给新对象: 执行构造函数中的代码: 返回新 ...

  2. javascript高级程序设计读书笔记-事件(一)

    读书笔记,写的很乱   事件处理程序   事件处理程序分为三种: 1.html事件2. DOM0级,3,DOM2级别  没有DOM1 同样的事件 DOM0会顶掉html事件   因为他们都是属性  而 ...

  3. JavaScript高级程序设计-读书笔记(2)

    第6章 面向对象的程序设计 创建对象 1.最简单方式创建Object的实例,如 var person = new Object(); person.name = “Greg”; person.age ...

  4. javascript高级程序设计读书笔记----面向对象的程序设计

        创建对象   工厂模式 function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = ...

  5. Javascript高级程序设计--读书笔记之面向对象(二)

    前面讲了面向对象的封装,这章我们就来说一说继承 1.原型链 实现原型链有一种基本模式,其代码大概如下 <script> function SuperType(){ this.propert ...

  6. Javascript高级程序设计--读书笔记之面向对象(一)

    哈哈哈万物皆对象,终于到了js的面向对象篇. 一.属性类型 (1)数据属性 数据属性包含一个数据值的位置,在这个位置可以写入和读取数值,数据属性有四个描述器行为的特性 [[Configurable]] ...

  7. javascript高级程序设计读书笔记

    第2章  在html中使用javascript 一般都会把js引用文件放在</body>前面,而不是放在<head>里, 目的是最后读取js文件以提高网页载入速度. 引用js文 ...

  8. JavaScript高级程序设计-读书笔记(7)

    第22章 高级技巧 1.高级函数 (1)安全的类型检测 在任何值上调用Object原生的toString()方法,都会返回一个[object NativeConstructorName]格式的字符串. ...

  9. JavaScript高级程序设计读书笔记之JSON

    JSON(JavaScript Object Notation)JavaScript对象表示法.JSON是JavaScript的一个严格的子集,利用了JavaScript中的一些模式来表示结构化数据. ...

随机推荐

  1. Yii 1.1 cookie删不掉

    我的cookie是这样设置的: $cookie = new CHttpCookie('username','Jack'); $cookie->expire = time()+60*60*24*3 ...

  2. webpack从入门到精通(一)

    1.webpack的使用背景: 目前国内前端开发都是基于模块化的 2.webpack的作用有哪些: 3.webpack四大核心理念: entry,output,loaders,plugins 4.使用 ...

  3. go语言从例子开始之Example24.通道同步

    我们可以使用通道来同步 Go 协程间的执行状态.这里是一个使用阻塞的接受方式来等待一个 Go 协程的运行结束. Example: package main import "fmt" ...

  4. bzoj 1176 cdq分治套树状数组

    题面: 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Inp ...

  5. 用私有构造器或者枚举类型强化SingleTon(单例)属性

    单例(singleton)就是一个只实例化一次的类.使类成为单例可能会使它的测试变得困难,因为除非它实现了作为其类型的接口,否则不可能用模拟实现来代替这个单例.下面是几种实现单例的方法: 1.共有静态 ...

  6. Table 'jiang.hibernate_sequence' doesn't exist

    spring+struts2+hibernate 运行报错 Table 'jiang.hibernate_sequence' doesn't exist 解决方法 一. 在hibernate.cfg. ...

  7. SQL中LEFT JOIN ON AND 与 LEFT JOIN ON WHERE的区别

    数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. ON...WHERE ' order by ts.id SQL执行过程: 生成临时表: ON条件:  ...

  8. Least Common Ancestors

    /* Least Common Ancestors * Au: Small_Ash */ #include <bits/stdc++.h> using namespace std; con ...

  9. Vue使用lib-flexible,将px转化为rem

    1.下载lib-flexible 我使用的是vue-cli+webpack,所以是通过npm来安装的 npm i lib-flexible --save 2.引入lib-flexible 在main. ...

  10. (54) C# 调用 kernel32.dll

    https://www.cnblogs.com/cwy173/archive/2010/10/02/1841321.html Kernel32 API AddAtom 向本地原子表添加一个字符串 Al ...