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 可以自己定制对象的原型```javascriptfunction 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__);// undefinedconsole.log(obj1.num1);// 1var obj2 = Object.create(obj1);console.log(obj2);// {}console.log(obj2.__proto__); // undefinedconsole.log(obj2.num); // 1

var obj = Object.create(null);// 创建obj空对象obj.num = 1;var obj1 = {count: 2}// 给obj添加一个prototype为obj1obj.__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).toStirngvar 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); // 1document.write(obj); // [object Object]document.write(obj2); // 报错// 使用document.write必须经过toString()的转换// 而obj2压根就没有Object.prototype 因此无法使用其中的toStringobj2.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'}
