一、原型:
1. 任何函数都有prototype属性(对象才有属性,函数也是对象);
2. 函数的prototype属性的值是个对象,这个对象就是原型(对象);
3. 作用:通过构造函数创建出来的对象可以直接去访问这个构造函数的prototype属性上的任意成员;
function Person(){}
/*function fn(){}
console.dir(Person); // 以对象形式打印
console.dir(fn); */
// 给原型对象添加color属性
Person.prototype.color = "red";
Person.prototype.legs = 2; // sayHi方法在内存中只有一份,在Person.prototype原型对象中
// 内存浪费问题
Person.prototype.sayHi = function () {
console.log("hello is me");
}
console.log( Person.prototype );
var p1 = new Person();
console.log(p1.color); // lime
p1.sayHi();
var p2 = new Person();
console.log(p2.legs); // 2
p2.sayHi();
// p1的sayHi和p2 的sayHi方法是同一个,地址是相同的
// 这个sayHi方法在 原型对象中
console.log(p1.sayHi == p2.sayHi); // true
小结:
原型:函数的prototype属性的值(对象)
作用:通过构造函数创建出来的实例对象可以直接去访问这个构造函数的prototype属性上的任意成员;
           可以使用原型对象来解决构造函数创建对象造成的内存浪费问题;
           把需要的方法添加到原型对象中;
           原型对象是函数自带的;
二、构造函数 原型对象 实例对象 三者关系
// 构造函数
function Person(){}
// Person.prototype 原型对象
Person.prototype.color = "red";
Person.prototype.legs = 2;
Person.prototype.sayHi = function () {
console.log("hello is me");
}
// 实例对象
var p1 = new Person();
console.log(p1.color); // red
console.log(p1.legs); // 2
p1.sayHi();
// Person创建的实例
var p2 = new Person();
console.log( p2.color );
console.log( p2.legs );
p2.sayHi();
console.log(p1.sayHi === p2.sayHi);
拟人化理解:
拟人化理解原型三角关系
构造函数 和 原型对象来说:配偶关系
1. 构造函数 通过 prototype属性来访问到原型对象
2. 原型对象 通过 constructor属性来访问到构造函数
构造函数 和 实例对象的关系: 母子关系
1. 构造函数通过new创建出来实例对象
2. 实例对象不能去直接访问到构造函数
原型对象 和 实例对象的关系: 父子关系
1. 实例对象通过__proto__属性访问原型对象上的任意成员
2. 实例对象通过原型对象的constructor属性可以间接的访问构造函数

三、__proto__属性

1. 任何对象都有__proto__属性;
2. 对象的__proto__属性的值是指向了当前构造函数的原型对象;
function Person(){}
var p = new Person();
console.log(p);
console.log( p.__proto__ ); // 原型对象
console.log( p.__proto__ == Person.prototype ); // true
要想访问原型对象,有两种途径:
1. 对于构造函数来说,通过prototype属性可以来访问到原型对象
2. 对象实例对象来说,通过__proto__属性可以来访问到原型对象
该属性的注意点:
 __proto__属性 私有属性,不是个标准属性(存有兼容问题,IE678不识别该属性)
不推荐这么去操作原型对象
 // p.__proto__.color = "lime";
 // 推荐方式:
Person.prototype.color = "red";
console.log( Person.prototype );

四、constructor属性

1. 该属性是原型对象自带的;
2. 原型对象的constructor属性的值指向了当前的构造函数;
function Person(){}
console.log( Person.prototype );
console.log( Person.prototype.constructor ); // Person
练习题:
function Person(){}
var p = new Person();
console.log( p.constructor == Person ); // true
// p Person的实例对象
// p.constructor ==> p实例对象去原型对象上拿到constructor属性去用的
// ==> Person
console.log( p.constructor == Person.prototype.constructor ); // true
// Person.prototype.constructor ==> Person
// p.constructor ==> Person

五、原型链

// 问题:
function Person(){}
var p = new Person();
// 问:p实例对象去调用toString方法,这个toString方法在哪?
console.log( p.toString() );
// 原型链:对象有 __proto__ 属性, 指向了当前的原型对象,原型对象也是对象,原型对象有__proto__属性,指向了原型对象的原型对象,这样一环套一环形成的链式结构,叫做原型链。
// 形象理解: 孩子有自己的爸爸,自己的爸爸也有爸爸,族谱(原型链)
function Person(){}
var p = new Person();
console.log( Person.prototype.__proto__ ); // 找爸爸
console.log( Person.prototype.__proto__.constructor );// 找妈妈 console.log( Person.prototype.__proto__ == Object.prototype );
console.log( Object.prototype.__proto__ ); // null
// 实例对象p的原型链:
// p ==> Person.prototype ==> Object.prototype ==> null;

六、内置对象的原型链

// Array
var arr = new Array();
// 实例对象arr的原型链:
// arr ==> Array.prototype ==> Object.prototype ==> null;
// console.log( Array.prototype.__proto__ );
// console.log( Array.prototype.__proto__.constructor ); // Date
var d = new Date();
// 实例对象d原型链:
// d ==> Date.prototype ==> Object.prototype ==> null; // Math 本身就是个对象(孩子),不是个构造函数,所以不能new
/*var m = new Math(); // error
m ==> */
// Math ==> Object.prototype ==> null;
// 规律: 任何对象的原型链上都有Object.prototype

七、属性查找原则

 // 1. 查找对象的属性的时候,首先会在对象自身上来查找是否有该属性,如果有,就返回属性的值
// 2. 如果没有,去原型对象上去查找,如果有,就返回属性的值
// 3. 如果没有,就会沿着对象的原型链继续在往上找,直到Object.prototype,如果有,就返回属性的值
// 4. 如果还没有,返回undefined
// 简单记忆:沿着对象的原型链往上查找
// 注意点:关键看对象身上是否有该属性,而不在乎其值
function Person(name, age){
this.color = "red";
this.name = name;
this.age = age;
}
Person.prototype.name = "lw";
Person.prototype.color = "lime";
Object.prototype.gender = "male";
var p = new Person("xm", 20);
console.log(p);
// p的原型链:
// p ==> Person.prototype ==> Object.prototype ==> null;
console.log( p.color );
console.log( p.name ); // xm
console.log( p.age ); // 20
console.log( p.gender ); // male
console.log( p.sex ); // undefined

案例:

/*function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.name = "lw";
Object.prototype.gender = "male";
var p = new Person(0, 0);
console.log(p);
// p的原型链:
// p ==> Person.prototype ==> Object.prototype ==> null; console.log( p.name ); // undefined
console.log( p.age ); // undefined
console.log( p.gender ); // male
console.log( p.sex ); // undefined*/
// 2.
function Person(name) {
// 有形参,无实参,形参的值undefined
if (name) {
// if没有执行
this.name = name
}
}
Person.prototype.name = 'ls'
Person.prototype.money = 100
var p = new Person()
console.log(p.name)
console.log(p.money)

八、属性设置原则

//  1. 如果对象有该属性,在设置的时候,其实就是把原来的值给覆盖掉,不会影响到原型上的属性
// 2. 如果对象没有该属性。在设置的时候,其实就是在添加该属性,不会影响到原型上的属性
// 简化理解: 有就覆盖,没有就添加。
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.name = "lw";
Object.prototype.gender = "male";
var p = new Person("xm", 20);
// 修改name属性 ==> 因为p自身有
// p.name = "ww";
// 给p添加gender属性,自身本来没有
p.gender = "不清楚";
console.log(p.gender); // 不清楚
console.log(Person.prototype.gender); // male
console.log(Object.prototype.gender); // male
/*console.log(p.name); // ww
console.log(Person.prototype.name); // lw
console.log(Object.prototype.name); // undefined*/

javascript之原型、原型链的更多相关文章

  1. 对Javascript 类、原型链、继承的理解

    一.序言   和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...

  2. 图解JavaScript中的原型链

    转自:http://www.jianshu.com/p/a81692ad5b5d typeof obj 和 obj instanceof Type 在JavaScript中,我们经常用typeof o ...

  3. JavaScript -- 继承与原型链

    JavaScript对象有一个指向一个原型对象的链,当试图访问一个对象的属性的时候,他不仅仅会在该对象上面搜寻,还会搜寻该对象的原型,以及对象的原型的原型,依次层层搜索,直到找到名字匹配的属性或者到达 ...

  4. JAVASCRIPT闭包以及原型链

    方法内部还有个方法,实例化父方法后,再次调用父方法,可以运行父方法内部的子方法,这样的程序就叫做闭包 DEMO如下: //function outerFn() { // var outerVar = ...

  5. javascript进阶-《原型对象和原型链》

    原创发布 by @一像素 2015.12 在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象Object 和 函数对象Function. 一般而言,通过new Fun ...

  6. JavaScript原型&原型链

    原型&原型对象 先来一段简单的代码: function Fun(name) { this.name = name } var obj = new Fun('obj') JavaScript中的 ...

  7. 浅谈Javascript中的原型、原型链、继承

    构造函数,原型,实例三者的关系 构造函数: 构造函数是创建对象的一种常用方式, 其他创建对象的方式还包括工厂模式, 原型模式, 对象字面量等.我们来看一个简单的构造函数: function Produ ...

  8. JavaScript ES5类 原型 原型链 组合、原型、寄生式继承

    ES5类 原型  原型链 继承 JavaScript中,原型是相对于构造函数(类)的叫法(或者说概念),原型链是相对于构造函数(类)的实例对象的叫法. 对于JavaScript对象,如果在对象自身上找 ...

  9. JavaScript中的原型、原型链、原型模式

    今天,咱来聊聊JavaScript中的原型跟原型链 原型跟原型模式 这一块的知识,主要是设计模式方面的. 首先,我们知道JavaScript是面向对象的.既然是面向对象,那它自然也有相应的类跟对象等概 ...

  10. 全面了解 Javascript Prototype Chain 原型链

    原型链可以说是Javascript的核心特征之一,当然也是难点之一.学过其它面向对象的编程语言后再学习Javascript多少会感到有些迷惑.虽然Javascript也可以说是面向对象的语言,但是其实 ...

随机推荐

  1. 关于Intege.valueOf()的使用

    原文链接:https://blog.csdn.net/weixin_37650458/article/details/85212730 1.Integer. valueOf()方法的作用     In ...

  2. iOS gif图显示问题

    问题 有时候需要显示gif动态图,让界面更加的绚丽,但是iOS默认只支持png,gpg图片.那么如何才能显示gif图呢? 解决方式 添加框架 CoreGraphics.framework ImageI ...

  3. kafka 数据存储和发送

    摘要 前面我们已经解释获取和更新metadata以及重要性,那么如何给topic 发送数据? kafkaclient和broker通信,有很多种情况,核心的broker提供的接口有6个 元数据接口(M ...

  4. C++基础入门知识:C++命名空间(名字空间)详解

    一个中大型软件往往由多名程序员共同开发,会使用大量的变量和函数,不可避免地会出现变量或函数的命名冲突.当所有人的代码都测试通过,没有问题时,将它们结合到一起就有可能会出现命名冲突. 例如小李和小韩都参 ...

  5. C++反射机制:可变参数模板实现C++反射(二)

    1. 概要   2018年Bwar发布了<C++反射机制:可变参数模板实现C++反射>,文章非常实用,Bwar也见过好几个看了那篇文章后以同样方法实现反射的项目,也见过不少从我的文章抄过去 ...

  6. LaTeX中的参考文献BibTex

    设置: BibTex代码及注释: 显示效果:

  7. 一个使用xlwings操作excel数据优化60倍处理效率的案例

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 老猿在将自己的博文数据(包括url地址.标题和阅读数量)从博客中获取后,使用xlwings保存到excel对象时发现,不同的处理方法性能相差非常大. ...

  8. 第14.16节 爬虫实战2:赠人玫瑰,手留余香! request+BeautifulSoup实现csdn博文自动点赞

    写在前面:本文仅供参考学习,请勿用作它途,禁止转载! 在<第14.14节 爬虫实战准备:csdn博文点赞过程http请求和响应信息分析>老猿分析了csdn博文点赞处理的http请求和响应报 ...

  9. PyQt(Python+Qt)学习随笔:Qt Designer中toolBar的floatable属性

    floatable属性用于保存工具栏是否可以作为独立小窗口拖放,其类型为bool类型,默认值为True,表示工具栏可以漂作为独立窗口拖放. 下图是漂浮在窗口上的工具栏案例: 可以通过isFloatab ...

  10. Xray批量化自动扫描

    关于Xray高级版破解: https://www.cnblogs.com/Cl0ud/p/13884206.html 不过好像新版本的Xray修复了破解的BUG,亲测Xray1.3.3高级版仍然可以破 ...