10.1 原型链是什么?原型链和原型是什么关系?为什么要叫原型链呢?
function Car() {};
var car = new Car();
console.log(Car.prototype);
console.log(car);
console.log(Car.prototype);
10.1.1 每一个对象都默认有__proto__属性,其存放着构造函数的prototype属性。
10.1.2 每一个对象的原型都有原型,包括原型本身。
Professor.prototype.tSkill = 'Java';
function Professor() {};
var professor = new Professor();
Teacher.prototype = professor;
function Teacher() {
this.mSkill = 'JS/JQ';
}
var teacher = new Teacher();
Student.prototype = teacher;
function Student() {
this.pSkill = 'HTML/CSS';
}
var student = new Student();
console.log(student);
student = {
pSkill:'HTML/CSS',
__proto__:teacher = {
mSkill:'JS/JQ',
__proto__:professor = {
__proto__:Professor.prototype = {
tSkill:'Java',
__proto__:Object.prototype = {
__proto__:null;
}
}
}
}
}
10.1.3 proto:沿着__proto__去找(原型)里的属性一层一层的去继承原型里的属性的这条链条叫做原型链,这层继承关系就叫做原型链。
10.2 原型链的终点是什么?
var obj = {};
console.log(obj.__proto__);
console.log(Object.prototype.__proto__ === null);
10.3 特殊的原型Function
function Foo() {};
var f1 = new Foo();
console.log(f1.__proto__ === Foo.prototype);
console.log(Foo.prototype.constructor === Foo);
console.log(Foo.prototype.__proto__ === Object.prototype);
console.log(Object.prototype === null);
var Foo = new Function('a', 'b', 'return a + b');
Foo(1, 2);
console.log(Function.prototype.constructor === Function);
console.log(Foo.__proto__ === Function.prototype);
var obj = new Object();
console.log(obj);
console.log(Object.__proto__ === Function.prototype);
var num = new Number(1);
console.log(num);
console.log(Number.__proto__ === Function.prototype);
var Foo = new Foo('a', 'b', 'return a + b');
Foo(1, 2);
console.log(Function.__proto__ === Function.prototype);
console.loog(Function.prototype.__proto__ === Object.prototype);
10.4 关于实例对象修改原型属性的问题?
10.4.1 引用类型值的属性
Professor.prototype.tSkill = 'Java';
function Professor() {};
var professor = new Professor();
Teacher.prototype = professor;
function Teacher() {
this.mSkill = 'JS/JQ';
this.students = {
alibaba:100,
baidu:200
}
}
var teacher = new Teacher();
Student.prototype = teacher;
function Student() {
this.pSkill = 'HTML/CSS';
};
var student = new Student();
student.students.alibaba = 200;
student.students.baidu = 100;
console.log(student);
console.log(teacher);
var student = {};
student.students.alibaba = 300;
10.4.2 原始类型值和引用类型值
Professor.prototype.tSkill = 'JAVA';
function Professor() {};
var professor = new Professor();
Teacher.prototype = professor;
function Teacher() {
this.mSkill = 'JS/JQ';
this.students = 100;
this.obj = {
num : 2
}
}
var teacher = new Teacher();
Student.prototype = teacher;
function Student() {
this.pSkill = 'HTML/CSS';
}
var student = new Student();
student.students++;
console.log(student);
console.log(teacher);
student.obj = { num: 3 };
console.log(student);
console.log(teacher);
function Person() {
this.smoke = function() {
this.weight--;
}
}
Person.prototype = {
weight:130
}
var person = new Person();
person.smoke();
console.log(person);
console.log(Person.prototype);
10.5 this指向问题
function Car() {
this.brand = 'Benz';
}
Car.prototype = {
brand : 'Mazada',
intro : function() {
console.log('我是' + this.brand + '车');
}
}
var car = new Car();
car.intro();
function Car() {
this = {
brand:'Benz',
__proto__ : Car.prototype
}
}
Car.prototype.intro();
10.6 对象创建## 与继承
var obj = {};
var obj2 = new Object();
console.log(obj);
console.log(obj2);
obj.__proto__.constructor === Object
obj2.__proto__.constructor === Object
function Foo() {};
var obj3 = new Foo();
obj3.__proto__.constructor === Foo;
function Obj() { }
var obj = new Obj();
console.log(obj.__proto__.__proto__.constructor);
10.7 Object.create()方法
function Obj() {};
Obj.prototype.num = 1;
var obj = new Obj();
console.log(obj);
var obj2 = Object.create(Obj.prototype);
console.log(obj2);
console.log(obj2.num);
new的功能:
1. 实例化对象
2. 调用构造函数初始化属性和方法
3. 指定实例对象的原型
var obj = Object.create(null);
console.log(obj);
var obj2 = Object.create(obj);
console.log(obj2);
console.log(obj2.__proto__);
var obj3 = Object.create(null);
obj3.__proto__ = {
num : 1
}
console.log(obj3.num);
Object.prototype.myCreate = function( proto ) {
function F() {};
F.prototype = proto;
return new F();
}
if (typeof Object.create !== "function") {
Object.create = function (proto, propertiesObject) {
if (typeof proto !== 'object' && typeof proto !== 'function') {
throw new TypeError('Object prototype may only be an Object: ' + proto);
} else if (proto === null) {
throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
}
if (typeof propertiesObject !== 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
function F() {}
F.prototype = proto;
return new F();
};
}
1. 不是所有的对象都是继承于Object.prototype,Object.create(null)方法创建的对象没有__proto__属性。
2. 不能自定义__proto__属性
10.8 原型方法的重写和toString()方法
var num = 1;
var obj = {};
var obj2 = Object.create(null);
document.write(num);
document.write(obj);
document.write(obj2);
num.toString(); ---> 包装类 ---> new Number(num).toString();
obj.toString(); ---> obj.prototype.toString();
obj2 并没有__proto__属性,所以并没有办法将值转为字符串类型,所以报错。
var num = new Number(1);
console.log(Object.prototype);
console.log(num.prototype);
10.9 call和apply方法
function fn() {
console.log('a');
}
fn();
function Car(brand, color) {
this.brand = brand;
this.color = color;
}
var newCar = {};
Car.call(newCar, 'benz', 'blue');
Car.apply(newCar, ['benz', 'red']);
---> 相当于
function Car(brand, color) {
newCar.brand = brand;
newCar.color = color;
}
console.log(newCar);
function Compute() {
this.plus = function(a, b) {
console.log(a + b);
};
this.minus = function(a, b) {
console.log(a - b);
};
}
function FullCompute() {
Compute.call(this);
this.div = function(a, b) {
console.log(a / b);
};
this.mul = function(a, b) {
console.log(a * b);
};
}
var fullCompute = new FullCompute();
fullCompute.plus(1, 2);
fullCompute.minus(1, 2);
fullCompute.div(1, 2);
fullCompute.mul(1, 2);