javascript之原型、原型链
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
// 构造函数
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);
三、__proto__属性
function Person(){}
var p = new Person();
console.log(p);
console.log( p.__proto__ ); // 原型对象
console.log( p.__proto__ == Person.prototype ); // true
// 推荐方式:
Person.prototype.color = "red";
console.log( Person.prototype );
四、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之原型、原型链的更多相关文章
- 对Javascript 类、原型链、继承的理解
一.序言 和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...
- 图解JavaScript中的原型链
转自:http://www.jianshu.com/p/a81692ad5b5d typeof obj 和 obj instanceof Type 在JavaScript中,我们经常用typeof o ...
- JavaScript -- 继承与原型链
JavaScript对象有一个指向一个原型对象的链,当试图访问一个对象的属性的时候,他不仅仅会在该对象上面搜寻,还会搜寻该对象的原型,以及对象的原型的原型,依次层层搜索,直到找到名字匹配的属性或者到达 ...
- JAVASCRIPT闭包以及原型链
方法内部还有个方法,实例化父方法后,再次调用父方法,可以运行父方法内部的子方法,这样的程序就叫做闭包 DEMO如下: //function outerFn() { // var outerVar = ...
- javascript进阶-《原型对象和原型链》
原创发布 by @一像素 2015.12 在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象Object 和 函数对象Function. 一般而言,通过new Fun ...
- JavaScript原型&原型链
原型&原型对象 先来一段简单的代码: function Fun(name) { this.name = name } var obj = new Fun('obj') JavaScript中的 ...
- 浅谈Javascript中的原型、原型链、继承
构造函数,原型,实例三者的关系 构造函数: 构造函数是创建对象的一种常用方式, 其他创建对象的方式还包括工厂模式, 原型模式, 对象字面量等.我们来看一个简单的构造函数: function Produ ...
- JavaScript ES5类 原型 原型链 组合、原型、寄生式继承
ES5类 原型 原型链 继承 JavaScript中,原型是相对于构造函数(类)的叫法(或者说概念),原型链是相对于构造函数(类)的实例对象的叫法. 对于JavaScript对象,如果在对象自身上找 ...
- JavaScript中的原型、原型链、原型模式
今天,咱来聊聊JavaScript中的原型跟原型链 原型跟原型模式 这一块的知识,主要是设计模式方面的. 首先,我们知道JavaScript是面向对象的.既然是面向对象,那它自然也有相应的类跟对象等概 ...
- 全面了解 Javascript Prototype Chain 原型链
原型链可以说是Javascript的核心特征之一,当然也是难点之一.学过其它面向对象的编程语言后再学习Javascript多少会感到有些迷惑.虽然Javascript也可以说是面向对象的语言,但是其实 ...
随机推荐
- 【ACwing 95】费解的开关——枚举 + 搜索
(题面来自ACwing) 你玩过"拉灯"游戏吗?25盏灯排成一个5x5的方形.每一个灯都有一个开关,游戏者可以改变它的状态.每一步,游戏者可以改变某一个灯的状态.游戏者改变一个灯的 ...
- java base64加解密
接上篇java Base64算法. 根据之前过程使用base64加解密,所以写成了工具类. 代码示例; public class Base64Util { private static Logger ...
- 现代富文本编辑器Quill的模块化机制
DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师.官方网站:devui.designNg组件库:ng-devui(欢迎S ...
- 装饰模式(Decorator Pattern)
代理模式:动态地给一个对象添加一些额外的职责,它比生成子类方式更为灵活. 优点:在某些时候装饰模式比继承(inheritance)要更加灵活 装饰模式的组成 (1)抽象组件:定义一个抽象接口,来规范准 ...
- Unity使用transform.Rotate进行三维旋转角度出现偏差
Unity使用transform.Rotate进行三维旋转角度出现偏差 情形 最开始遇到该问题的情况比较复杂,另写了一个例子.情形如下: 一个立方体上挂载脚本: transform.Rotate(25 ...
- Jmeter代理服务器录制脚本--浏览器拦截访问链接
在 Jmeter性能测试的过程中您是否会遇到代理服务器无法打开浏览器,无法录制脚本的情况呢? 在测试过程中,我也遇到过这样的问题,希望能帮到正在找寻答案的你.... Jmeter录制脚本时,跟http ...
- android studio报butterknife错误
Error:Execution failed for task ':shipper:javaPreCompileDebug'.> Annotation processors must be ex ...
- 关于建立老猿Python研学群的公告
3个月前有人建议老猿建立一个Python学习交流群,老猿自己学习Python也没多久,因此没有考虑这个事情,最近又有几个朋友在请我建立这样一个群,犹豫再三,老猿决定还是答应了,因为最近关注老猿Pyth ...
- FFmpeg在Android Studio中断点调试
一般情况下在Android平台使用FFmpeg为动态库或静态库的形式,只能通过设置FFmpeg日志回调来看一些FFmpeg输出的日志,有时需要debug来查看FFmpeg内部执行过程,本文记录一下在A ...
- 记一次MacPro风扇一直转的问题排查
1.查看CPU占用最高的进程 借助活动监视器,查看CPU占用最高的进程,可以观察到是Chrome浏览器 2.打开Chrome的任务管理器 2.1.查看CPU占用最高的chrome进程 3.分析和结束进 ...