给一个对象存值 没有这个属性就直接创建这个属性 有这个属性就更新
取一个对象的属性值 自己没有就会取原型对象 也没有就取原型的原型 直到null都没有 取出undefined
// 1.
var obj = {
name: 'karen'
};
obj.age = 20; // 添加age属性 保存20
obj.name = 'jack'; // 更新name属性 jack
var re = obj.age; // 取出age属性的值
var re2 = obj.x; // 取出x属性的值 但是没有x属性 取出undefined
var re3 = obj.name; // 取出最后一次修改的值
console.log(re, re2, re3);
// 2.
function fn(name) {
this.name = name;
};
fn.prototype = {
age: 30
};
var obj = new fn('karen');
obj.age = 20;
console.log(obj);
obj.name = 'jack';
var re = obj.age;
var re2 = obj.x;
var re3 = obj.name;
console.log(re, re2, re3); // 20 undefined 'jack'
系统内置构造函数的原型属性是不可以修改的 可以操作这个对象的属性
// 1.
Array.prototype.a = 200; // 所有的数组都有a属性200
Array.prototype = {
name: 'karen' // 不会报错 但是也不会生效(跳过编译)
};
var arr = [10, 203, 4];
console.log(arr.a, arr); // 200 [10, 203, 4]
console.log(arr.name, arr); // undefined [10, 203, 4]
// 2.
function fn() {
this.age = 20;
};
fn.prototype = {
life: 1,
baba: {
name: 'jack',
arr: [102, 30, 40]
}
};
var f1 = new fn();
f1.baba.name = 'karen'; // baba才是原型对象的属性 没有修改原型对象的成员就可以
f1.baba.arr = [123, 123, 123];
var f2 = new fn();
console.log(f2.baba.name); // karen
练习题
function Parent() {
this.a = 1;
this.b = [1, 2, this.a];
this.c = {
demo: 5
};
this.show = function () {
console.log(this.a, this.b, this.c.demo);
}
}
function Child() {
this.a = 2;
this.change = function () {
this.b.push(this.a);
this.a = this.b.length;
this.c.demo = this.a++;
}
}
Child.prototype = new Parent();
// 后面的代码用Child函数创建的对象的原型对象
// Child.prototype = O1{a:1,b:[1,2,1],c:{demo:5},show:上面的函数,__proto__:O3{}}
var parent = new Parent();
// parent = O2{a:1,b:[1,2,1],c:{demo:5},show:上面的函数,__proto__:O3{}}
var child1 = new Child();
// child1={a:11,change:上面的函数,__proto__:O1}
var child2 = new Child();
// child2={a:12,change:上面的函数,__proto__:O1}
child1.a = 11; // 无论child1的原型链上是否有a成员 都会把a添加/更新到child1自己上
child2.a = 12;
parent.show();
// console.log(this.a, this.b, this.c.demo) ==> parent就是this 也就是O2对象 O2.a=>1 O2.b=>[1,2,1] O2.c=>5
// 打印 1 [1,2,1] 5
child1.show();
// show函数是原型对象的方法 child1自己没有 就访问了原型的 但是调用者(函数内部的this)是child1 ==> console.log(this.a, this.b, this.c.demo)
// this.a=>11 this.b=>自己没有 访问原型的 [1,2,1] this.c.demo=>访问原型的 5
// 打印 11 [1,2,1] 5
child2.show();
// how函数是原型对象的方法 child1自己没有 就访问了原型的 但是调用者(函数内部的this)是child2 ==> console.log(this.a, this.b, this.c.demo)
// this.a=>12 this.b=>访问原型的 [1,2,1] this.c.demo=>访问原型的 5
// 打印 12 [1,2,1] 5
child1.change();
/*
this是child1
this.b.push(this.a); b是原型对象的属性 但是这个代码没有修改b 只是操作了b内部的数据 是可以让原型对象内部的数据改变的 this.a取值会优先取原型链最顶层的属性11 ==> 原型对象的数组末尾添加11 [1,2,1,11]
this.a = this.b.length; 给child1自己添加/更新a属性 值为4(child1的原型对象的属性b的长度)
this.c.demo = this.a++; 先取值4 再把a的值加1(5) (this.c属性是原型对象的属性 但是没有修改这个属性的情况下是可以操作其内部的数据的)
*/
child2.change();
/*
this是child2
this.b.push(this.a); ==> 同上 b是原型对象的属性 但是这个代码没有修改b 只是操作了b内部的数据 是可以让原型对象内部的数据改变的 this.a取值会优先取原型链最顶层的属性12 原型对象的数组末尾添加12 [1,2,1,11,12]
this.a = this.b.length; 给child1自己添加/更新a属性 值为5(child2的原型对象的属性b的长度)
this.c.demo = this.a++; 先取值5 再把a的值加1(6) (this.c属性是原型对象的属性 但是没有修改这个属性的情况下是可以操作其内部的数据的)
*/
parent.show();
// show函数内部的this是parent
// console.log(this.a, this.b, this.c.demo)
// 打印 1 [1,2,1] 5
child1.show();
// show函数内部的this是child1
// console.log(this.a, this.b, this.c.demo)
// 打印 5 [1,2,1,11,12] 5
child2.show();
// show函数内部的this是child2
// console.log(this.a, this.b, this.c.demo)
// 打印 6 [1,2,1,11,12] 5