1. 原型
prototype: 是构造函数的原型
proto: 存放原型的容器
2.原型链
- 沿着proto往上去找原型的属性,一层一层的去继承原型的属性这个链条称为原型链.
- 原型链的顶端是Object.prototype
- 原型本身也有原型
- 原型链上的增删改只能针对自身,不能针对上级
function Car(){}
var car = new Car();
console.log(Car.prototype);
// Car.prototype = {
// constructor: f Car()
// __proto__: Object
// }
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(studennt);
Professor.prototype.tSkill = 'JAVA';
function Professor(){
}
var professor = new Professor();
Teacher.prototype = professor;
function Teacher(){
this.mSkill = 'JS/JQ';
this.students = 500;
this.sucess = {
alibaba: '28',
tencent: '30'
}
}
var teacher = new Teacher();
Student.prototype = teacher;
function Student(){
this.pSkill = 'HTML/CSS';
}
var student = new Student();
console.log(student.sucess);
student.sucess.baidu = '100';
student.students++;
// 相当于student增加了一个students属性,然后+1 teacher里面无变化
console.log(teacher, student);
引用值可以修改,原始值不可以。
访问对象的属性和方法时,优先查找自身的属性和方法,没有的话根据原型链一层一层的去查找。
this谁用指向谁
prototype实际上也是一个对象
3.对象继承
3.1 创建对象
- 字面量
- 构造函数创建 ```javascript var obj1 = {}; console.log(obj1);
var obj2 = new Object(); // 一般不用 conosle.log(obj2);
var Obj(){} var obj3 = new Obj();
console.log(obj3.proto === Obj.prototype);// true
<a name="zihc0"></a>
## 3.2 Object.create(对象、null)
1. 当参数为null的时候可以创建没有原型的对象
1. Object.create 可以自己定制对象的原型
```javascript
function Obj(){}
Obj.prototype.num = 1;
var obj1 = Object.create(Obj.prototype);
var obj2 = new Obj();
console.log(obj1, obj2)
3.3 不是所有的对象都继承于Object.prototype
var obj = {};
console.log(obj);// {}
console.log(obj.__proto__); // {constructor:...,...}
var obj1 = Object.create(null);
// 里面不继承,因为这个对象没有原型
console.log(obj1); // {}
obj1.num = 1;
console.log(obj1); // {num: 1}
console.log(obj1.__proto__);// undefined
console.log(obj1.num1);// 1
var obj2 = Object.create(obj1);
console.log(obj2);// {}
console.log(obj2.__proto__); // undefined
console.log(obj2.num); // 1
var obj = Object.create(null);
// 创建obj空对象
obj.num = 1;
var obj1 = {
count: 2
}
// 给obj添加一个prototype为obj1
obj.__proto__ = obj1;
console.log(obj);
var obj2 = {
count: 3
}
console.log(obj2);// {count:3}
console.log(obj.count);// undefined 因为obj原型是自造的 所以是无效的 __proto__必须是系统内置的。
3.4 undefined,null不能使用 toString()方法
var num = 1 ;
console.log(num.toString());
// new Number(1).toStirng
var num2 = new Number(num);
console.log(num2.toString()); // 1
// 这个是调用的自己toString方法
// 原始值是没有属性的 只有引用值有属性
// 但是可以通过包装类 将数字转换为数字对象 字符串转换为字符串对象
// undefined null 不能通过包装类转换为对象
// 因为它没有自己的原型就无法继承Object.prototyoe 也就无法使用toString
3.5document.write会打印对象的toString()方法
var num = 1;
var obj = {};
var obj2 = Object.create(null);
document.write(num); // 1
document.write(obj); // [object Object]
document.write(obj2); // 报错
// 使用document.write必须经过toString()的转换
// 而obj2压根就没有Object.prototype 因此无法使用其中的toString
obj2.toString = function(){ // 可以手动添加toString方法
return 'haha'
}
document.write(obj2);
3.6 通过Object.prototype.toString.call方法判断对象的类型
var toString = Object.prototype.toString;
var date = new Date();
// [基本类型 引用类型]
console.log(toString.call(1)); // [object Number]
console.log(toString.call('1')); // [object String]
console.log(toString.call(undefined)); // [object Undefined]
console.log(toString.call(null)); // [object Null]
console.log(toString.call([])); // [object Array]
console.log(toString.call({})); // [object Object]
console.log(toString.call(true));// [object Boolean]
console.log(toString.call(/\d+/));// [object RegExp]
console.log(toString.call(date));// [object Date]
3.7 call,apply更改this指向
function Car(brand, color){
this.brand = brand;
this.color = color;
}
var newCar = {};
// Car.call(newCar, 'Benz', 'red');
Car.apply(newCar, ['Benz', 'red']);
console.log(newCar);// {brand: 'Benz', color:'red'}