js原型链的理解
2016-03-15 16:57
507 查看
function Obj(){};
Obj.prototype.a="我是a1";
Obj.prototype.b={c:"我是c1"}
var o1=new Obj();
o1.a="我是a2";
o1.b.c="我是c2";
var o2=new Obj();
console.log(o2.a)
console.log(o2.b.c)
当 o1.a 通过等号修改时会为实例创建一个新的属性a且覆盖了prototype中的同名属性a 并切断原来的引用 所以原型上的a并不会被修改 ,
而 o1.b.c 直接引用了o1原型链上的 对象 b 的 静态属性 c 所以原型链上的b.c 会随着o1.b.c 的重新赋值 而改变
o1.a="我是a2"; 是为对象o1添加新属性a并覆盖原有的同名属性 原型链并未改变所以console.log(o2.a) 结果是 "我是a1"
o1.b.c="我是c2"; 修改了原型链上的对象b 的 静态属性c console.log(o2.b.c) 结果是 "我是c2";
---------------------------------------------对上面的理解做进一步的测试--------------------------------------------------
function Obj(){};
Obj.prototype.b = function(){}
Obj.prototype.b.prototype.c="我是c1";
var o1 = new Obj();
o1.b.c = "我是c2"; //这里的 o1.b 不是一个新的实例 o1直接引用了原型链上的对象b 所以原型链上的c 已被 o1.b.c 修改
var o2 = new Obj();
console.log(o2.b.c); // "我是c2"
function Obj(){};
Obj.prototype.b = function(){}
Obj.prototype.b.prototype.c="我是c1";
var o1 = new Obj.prototype.b();
o1.c = "我是c2"; //这里的 o1 是对象Obj.prototype.b的一个新的实例 重新赋值的时候原型链的引用已被切断 新的属性将覆盖对象o1上原有的同名属性 所以原型链上的c 未被 o1.c 修改
var o2 = new Obj.prototype.b();
console.log(o2.c); // "我是c1"
----------------------------------- 个人理解 难免出错 如有发现 可在下方评论及时指出 --------------------------------------------
补充:
当打印o2.a 的时候 首先是在当前实例对象o2上寻找变量a 如果没有找到再向上一层也就是对象原型上查找 如还未找到 以此类推
所以 实例对象上的属性 并不会影响原型上的属性 只是一个查找顺序的问题
每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去
一、prototype和__proto__的概念
prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象。它是显示修改对象的原型的属性。
__proto__是一个对象拥有的内置属性(请注意:prototype是函数的内置属性,__proto__是对象的内置属性),是JS内部使用寻找原型链的属性。
用chrome和FF都可以访问到对象的__proto__属性,IE不可以。
二、new 的过程
new的过程拆分成以下三步:
(1) var p={}; 也就是说,初始化一个对象p
(2) p.__proto__ = Person.prototype;
(3) Person.call(p); 也就是说构造p,也可以称之为初始化p
关键在于第二步,我们来证明一下:
这段代码会返回true。说明我们步骤2是正确的。
三、示例
p是一个引用指向Person的对象。我们在Person的原型上定义了一个sayName方法和age属性,当我们执行p.age时,会先在this的内部查找(也就是构造函数内部),如果没有找到然后再沿着原型链向上追溯。
这里的向上追溯是怎么向上的呢?这里就要使用__proto__属性来链接到原型(也就是Person.prototype)进行查找。最终在原型上找到了age属性。
Obj.prototype.a="我是a1";
Obj.prototype.b={c:"我是c1"}
var o1=new Obj();
o1.a="我是a2";
o1.b.c="我是c2";
var o2=new Obj();
console.log(o2.a)
console.log(o2.b.c)
当 o1.a 通过等号修改时会为实例创建一个新的属性a且覆盖了prototype中的同名属性a 并切断原来的引用 所以原型上的a并不会被修改 ,
而 o1.b.c 直接引用了o1原型链上的 对象 b 的 静态属性 c 所以原型链上的b.c 会随着o1.b.c 的重新赋值 而改变
o1.a="我是a2"; 是为对象o1添加新属性a并覆盖原有的同名属性 原型链并未改变所以console.log(o2.a) 结果是 "我是a1"
o1.b.c="我是c2"; 修改了原型链上的对象b 的 静态属性c console.log(o2.b.c) 结果是 "我是c2";
---------------------------------------------对上面的理解做进一步的测试--------------------------------------------------
function Obj(){};
Obj.prototype.b = function(){}
Obj.prototype.b.prototype.c="我是c1";
var o1 = new Obj();
o1.b.c = "我是c2"; //这里的 o1.b 不是一个新的实例 o1直接引用了原型链上的对象b 所以原型链上的c 已被 o1.b.c 修改
var o2 = new Obj();
console.log(o2.b.c); // "我是c2"
function Obj(){};
Obj.prototype.b = function(){}
Obj.prototype.b.prototype.c="我是c1";
var o1 = new Obj.prototype.b();
o1.c = "我是c2"; //这里的 o1 是对象Obj.prototype.b的一个新的实例 重新赋值的时候原型链的引用已被切断 新的属性将覆盖对象o1上原有的同名属性 所以原型链上的c 未被 o1.c 修改
var o2 = new Obj.prototype.b();
console.log(o2.c); // "我是c1"
----------------------------------- 个人理解 难免出错 如有发现 可在下方评论及时指出 --------------------------------------------
补充:
当打印o2.a 的时候 首先是在当前实例对象o2上寻找变量a 如果没有找到再向上一层也就是对象原型上查找 如还未找到 以此类推
所以 实例对象上的属性 并不会影响原型上的属性 只是一个查找顺序的问题
每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去
一、prototype和__proto__的概念
prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象。它是显示修改对象的原型的属性。
__proto__是一个对象拥有的内置属性(请注意:prototype是函数的内置属性,__proto__是对象的内置属性),是JS内部使用寻找原型链的属性。
用chrome和FF都可以访问到对象的__proto__属性,IE不可以。
二、new 的过程
var Person = function(){}; var p = new Person();
new的过程拆分成以下三步:
(1) var p={}; 也就是说,初始化一个对象p
(2) p.__proto__ = Person.prototype;
(3) Person.call(p); 也就是说构造p,也可以称之为初始化p
关键在于第二步,我们来证明一下:
var Person = function(){}; var p = new Person();
alert(p.__proto__ === Person.prototype);
这段代码会返回true。说明我们步骤2是正确的。
三、示例
var Person = function(){}; Person.prototype.sayName = function() { alert("My Name is Jacky"); }; Person.prototype.age = 27; var p = new Person(); p.sayName();
p是一个引用指向Person的对象。我们在Person的原型上定义了一个sayName方法和age属性,当我们执行p.age时,会先在this的内部查找(也就是构造函数内部),如果没有找到然后再沿着原型链向上追溯。
这里的向上追溯是怎么向上的呢?这里就要使用__proto__属性来链接到原型(也就是Person.prototype)进行查找。最终在原型上找到了age属性。
相关文章推荐
- JavaScript原型学习笔记
- js封常用类
- JSP自定义标签案例分析
- JS中offsetTopclientTop、scrollTop、offsetTop
- Hibernate+JSP+Servlet应用(OpenSessionInView模式)
- seaJS 简单上手
- JSP自定义标签基础知识学习
- JavaScript中的关键字之prototype的使用
- JavaScript EXT 创建一个 form 表单并提交
- megapix-image插件 使用Canvas压缩图片上传 MegaPixImage.js下载
- 最简单的JSP 文件
- js自定义函数时间显示(重构时间函数)
- js遍历拼接list集合对象,JSONArray数组
- js 截取某个字符前面或者后面的字符串
- JSP的九大内置对象
- javascript实现html延时按钮
- doT.js 爱好者
- js获取当前页面的URL
- Ajax——json
- 使用maven 创建SSi框架的地址,以及echarts类库的地址 json_lib的地址