一、原型:
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. Java基础教程——System类

    System类 java.lang.System类代表当前Java程序的运行平台. |-可以做输入输出,垃圾回收:(此处不讲) |-可以获取时间: |-可以获取环境变量: |-可以获取系统信息: |- ...

  2. Pytest学习(十二)-生成HTML报告插件之pytest-html的使用

    环境前提 Python3.6+ 安装插件 pip3 install pytest-html -i http://pypi.douban.com/simple/ --trusted-host pypi. ...

  3. 如何在Linux下关闭ARP协议

    方法一:临时关闭ARP协议 echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignoreecho 2 > /proc/sys/net/ipv4/conf ...

  4. Linux服务器学习----haproxy+keepalived

    实验需要4台虚拟机,两台做服务器,两台做代理服务器 www1:ip:10.30.40.11       hk1: 代理:10.30.40.13(hk1.netdj.net) www2:ip  10.3 ...

  5. Clickhouse 入门

    clickhouse 简介 ck是一个列式存储的数据库,其针对的场景是OLAP.OLAP的特点是: 数据不经常写,即便写也是批量写.不像OLTP是一条一条写 大多数是读请求 查询并发较少,不适合放置先 ...

  6. fist-第五天冲刺随笔

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE1 这个作业要求在哪里 https://edu.cnblogs.com/campus/fz ...

  7. 基于 MongoDB 动态字段设计的探索

    一.业务需求 假设某学校课程系统,不同专业课程不同 (可以动态增删),但是需要根据专业不同显示该专业学生的各科课程的成绩,如下: 专业 姓名 高等数学 数据结构 计算机 张三 90 85 计算机 李四 ...

  8. 为什么 redo log 具有 crash-safe 的能力,是 binlog 无法替代的?

    昨天在复习 MySQL 日志相关的知识,学的东西过一段时间后就会遗忘,遗忘后再重新思考,往往会有新的收获.想到几个问题,把它记录下来. 为什么 redo log 具有 crash-safe 的能力,而 ...

  9. moviepy音视频剪辑:颜色相关变换函数blackwhite、colorx、fadein/out、gamma_corr、invert_colors、lum_contrast、mask_color介绍

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 在<moviepy音视频剪辑:moviepy中的剪辑基类Clip详解>介绍了剪辑基类的fl.fl_time.fx方法,在<movi ...

  10. Monkey 部署环境

    Monkey的介绍 它是Android系统自带一个命令行工具,可以运行在模拟器里或者真是设备中运行. Monkey是发送伪随机用户事件的工具. Monkey向系统发送伪随机的用户事件流,实现对正在开发 ...