20170825-继承&原型链
属性
-
自有属性
自己定义的属性
-
继承属性
继承来的属性
// 判断某个属性是否为该对象的自有属性(非继承得来)
对象名.hasOwnProperty( '属性名' );
对象
在计算机科学中, 对象是指内存中的可以被 标识符 (变量、函数、属性)引用的一块区域.
继承
JavaScript中,子对象可以继承父对象的属性(且是单继承)
console.log( [Object.name](http://object.name) ); // Object
var o = new Object(); // 创建Object的子对象 o
那,平时是怎么继承的呢?
var q = {
a: 2,
m: function(){
return this.a + 1;
}
};
console.log( q.m() ); // 输出 3
var p = Object.create( q ); // 用指定的原型对象及其属性方法创建新对象
p.a = 12;
console.log( p.m() ); // 输出 13, p 继承了 q 的 m()
这就对了,父元素定义的属性,子元素可以继承,这里的 a 和 m 属性,属于继承属性
// 构造函数
var Student = function(name){
[this.name](http://this.name) = name;
this.age = 12;
};
// 给构造函数多赋点值
Student.prototype = {
hello = function(){console.log('hello' + ' ' + this.name)};
};
// 上面那步改变了一些不该改的东西,需要手动改回来
Student.prototype.constructor = Student;
// 或者,一次只定义一个属性,可以不修改 constructor
[Student.prototype.tel](http://student.prototype.tel) = '';
上面那张图,构造函数Student有个prototype属性,指向一个对象(Student.prototype),由 new Student 创建的对象继承 Student.prototype 里面的属性和 Student 里面的属性。但是,继承自 Student 的属性,子对象会自己创建同名属性并拷贝值,而继承自 Student.prototype 的属性,所有子对象会共享该属性,当 Student.prototype.hello 的值更改后,子对象.hello 的值也会更改。
xiaoming —> Student.prorotype —> Object.prototype —> null
原型链: 对象3 —> 对象1 —> Student.prototype —> Object.prototype —> null
// 构造函数(虽然现在讨论的是对象的继承,构造函数也是可以继承的)
var Student = function(name){
[this.name](http://this.name) = name;
this.age = 12;
};
// 给“构造函数”多赋点值
Student.prototype = {
hello = function(){console.log('hello' + ' ' + this.name)};
};
// 上面那步改变了一些不该改的东西,需要手动改回来
// 其实修改的是 prototype对象的contructor属性,指向对象的构造函数
Student.prototype.constructor = Student;
// 创建子对象1 子对象2
var hong = new Student('hong');
var ming = new Student('ming');
// 创建子对象3
var mh = Object.create( hong );
console.log( hong.__proto__ === Student.prototype );
// true 对象 hong 的原型是 Student.prototype
console.log( hong.__proto__ === Student );
// false 不是 Student,继承时,对象继承的是对象
console.log( typeof(Student.prototype) ); // object
console.log( mh.__proto__ === hong ); // true 子对象的原型是父对象,父对象修改自己属性时,所有通过new创建的子对象的对应属性也会被实时修改,而修改构造函数则不行。
// 在prototype里面覆盖构造函数的同名属性是无效的
当调用子对象的属性时,会查找当前对象内有无定义,没有则沿原型链向上查找,直到找到该属性的定义,若查找到null还没找到,则返回undefined
构造函数的继承
// 构造函数的继承
var Animal = function(name, age){
this.name = name;
this.age = age;
}
Animal.prototype.sayName = function(){
console.log( this.name );
}
Animal.prototype.sayAge = function(){
console.log( this.age );
}
var Dog = function(name, age, weight){
// 继承 Animal 的两个属性
Animal.call( this, name, age );
this.weight = weight;
}
// 继承 Animal 的两个方法,必须在创建对象前继承,对象才能调用
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
Dog.prototype.lookDoor= function(){
console.log( 'wangwangwang~~~' );
}
var Bird = function(name, age, color){
// 继承 Animal 的两个属性
Animal.call( this, name, age );
this.color = color;
}
Bird.prototype.fly = function(){
console.log( 'fly~~~' );
}
var dog1 = new Dog('哈士奇', 8, 10);
var bird1 = new Bird('麻雀', 1, 'red');
console.log( dog1 );
console.log( bird1 );
console.log('--------------------');
dog1.sayName();
推荐
MDN-继承与原型链
以上均为自学结果,欢迎各路高手指教。
网友评论