javascript中的原型
关于js中prototype,在js程序员中已经是个老生长谈的话题了。
虽然说很简单,但是在新手中却常常造成困惑,那么就再次拎出来谈一谈。
1 题目
让我们从一个题目开始我们的话题,请看
var f = function(){};
f.prototype.obj = {name:"jack",age:18};
var s = new f();
s.obj.name = "tom";
var t = new f();
console.log(t.obj.name);
请问,会打印出什么?
答案应该是tom,你猜对了吗?
或许你对了,或许你错了,都不要紧,请继续看下面的问题
var f = function(){};
f.prototype.obj = {name:"jack",age:18};
var s = new f();
s.obj = {name:"tom"};
var t = new f();
console.log(t.obj.name);
请问这次又是什么?
答案应该是jack,这次你对了吗?
你或许会疑惑,不是跟刚才的题目差不多嘛?为什么结果却不同呢?
2 解释
好吧,让我们抛开刚才的题目,想来回答一个问题,原型是什么?
简单的说,原型就一个备用品。
备用就很好理解了,如果我有,就用我的;如果我没有,那就用我备用品里的。
让我们来再看上面题目中的差异:
第一种方式:
s.obj.name = "tom";
s作为new出来的一个实例,它没有obj属性对象,所以它就只能使用原型上的obj了,然后修改了原型上的obj的name属性。
t在后面被new出来,它也没有obj属性对象,使用它也只能用原型上的obj。
而这个时候原型上的obj的name属性已经被修改过了,所以t.obj.name就是tom。
第二种方式:
s.obj = {name:"tom"};
在这里{name:”tom”}是一个新的对象,然后就赋值给了s.obj,这个时候s就有了自己的obj
这个时候s还会去访问在原型上的obj吗?不会了
所以原型上的obj属性也不会被修改
由此可以推论后面的t.obj.name就是没有被修改过的原型上的obj.name,所以也就是jack了