原型链
函数对象都有自己的原型。
function Car() { }var car = new Car();console.log(Car.prototype);//构造函数Car的原型console.log(car);//原型链 car.__proto__.__proto__
沿着proto 这个链条网上找属性的链条就是原型链
实例化对象不可以修改原型上的原始值。??? car.proto.age =13;
- 如果原型上的属性是原始值类型。那么实例化对象就会将原型上的属性添加到自身。并且赋值。 ```javascript /**原始值不可以修改*/
function Professor() { }
Professor.prototype.tSkill = “Java”;//将Professor原型上的tSkill 赋值为Java;
var professor = new Professor();
// professor = {
// proto:{
// constructor:Professor(),
// tSkill:’Java’
// }
// }
Teacher.prototype = professor;//将Teacher的原型上赋值为professor这个实例化对象; // teacher={ // mSkill:’JS/JQ’, // proto: { // proto:{ // constructor:Professor(), // tSkill:’Java’ // } // } // } function Teacher() { this.mSkill = “JS/JQ”;//如果不new或者执行。this就没有任何意义。new的情况下 mSkill 就变成了实例化对象的一个属性. } var teacher = new Teacher();//实例化Teacher这个构造函数,new之后this指向teacher
Student.prototype = teacher;//将Student的原型赋值为teacher这个实例化对象
function Student() { this.pSkill = “HTML/CSS”;//同上。 } var student = new Student();
console.log(student); //修改原始值。 student.mSkill = ‘Python’; //如果student要修改老师的mSkill,因为修改的是原始值。 //则会访问到teacher中的mSkill 给自己再添加一个相同的属性和值。
// student:{ // pSkill:’HTML/CSS’, // mSkill: ‘Python’ // proto:{ // mSkill:’JS/JQ’, // proto: { // proto:{ // constructor:Professor(), // tSkill:’Java’ // } // } // } // }
<a name="oUa1s"></a>#### 实例化对象可以修改原型上的引用值。1. 实例化对象直接就可以修改原型上的引用值。```javascript/********************************************引用值可以修改*****************************************************/function Professor() {}Professor.prototype.tSkill = 'Java';//在Professor 原型上添加tSkill;var professor = new Professor();//实例化professorTeacher.prototype = professor;//Teacher的原型赋值为professorfunction Teacher(){this.mSkill = 'JS/JQ';this.success ={'ali':100,'baidu':200,'tencent':90}//success 是引用值。}var teacher = new Teacher();Student.prototype = teacher;//Student的原型赋值为teacherfunction Student(){this.pSkill = 'HTML/CSS';}var student = new Student();console.log('before', student);//修改之前studentstudent.success.baidu = 100;//将student原型上的success.baidu修改为100;console.log('after', student);//修改之后student sucess.baidu 从200变成100;
this指向
function Car(){this.brand = 'Benz';}Car.prototype={brand:'Mazda',intro:function(){console.log('我是'+ this.brand +'车');}}// 我是Mazda车;对象内部this就指向对象本身。Car.prototype.intro();//实例化 carvar car = new Car();//我是Benz车car.intro();
function Person(){this.smoke = function(){this.weight--;}}Person.prototype={weight:130}//将person 原型赋值为一个新对象var person = new Person();// 实例化一个person对象person.smoke();//此时person会从Person的原型上读取weight属性。//因为weight是原始值类型、所以把这个属性添加到自身。赋值为129console.log(person);console.log(Person.prototype);//130
对象
创建方法
- var obj ={};
- var obj = new Object();
原型也是对象,原型的原型是由系统默认的Object构造出来的
function Obj() {}var obj = new Obj();//obj.__proto__===Obj.prototype trueconsole.log(obj.__proto__);
对象的方法
Object.create
_
function Obj() { };//构造函数的原型上定义一个num赋值为3。Obj.prototype.num = 3;//以Obj.prototype为原型创建了obj1 obj1的原型和var obj1 = Object.create(Obj.prototype);//实例化obj2var obj2 = new Obj();/*new 的作用。实例化了obj2调用构造函数Obj的初始化属性和方法。指定实例对象的原型*///obj1的原型和obj2的原型完全相等console.log(obj1.__proto__ === obj2.__proto__); //true;
var obj1 = Object.create(null);//将obj1的原型赋值为null;obj1.num = 1;//obj1添加了一个num属性。var obj2 = Object.create(obj1);//以obj1为原型创建了obj2;console.log(obj2);// {// __proto__: obj1 -> {// name: 1// }// }console.log(obj2.num);//1
toString
- undefined,null 不能经过包装类。所以不能继承Object 的属性和方法
- number有string因为有包装类 ```javascript var num = 1;
num.toString(); //由于1是没有toString 方法。所以只能先转成包装类。new Number(num)->toString()
var num2 = new Number(num);
document.write(num2); //这document.write会隐式把num2 转换成string;
3. 重写toString方法```javascriptObject.prototype.toString.call('1')"[object String]"Object.prototype.toString.call(1)"[object Number]"Object.prototype.toString.call(true)"[object Boolean]"Object.prototype.toString.call(undefined)"[object Undefined]"Object.prototype.toString.call(null)"[object Null]"Object.prototype.toString.call(function(){})"[object Function]"Object.prototype.toString.call({name:1})"[object Object]"Object.prototype.toString.call([1,2,3])"[object Array]"
call/apply更改this指向
function test(){console.log(1);}test();//test.call() 调用函数时。系统隐式增加了.call;
例子
//加减计算方法function Compute(){this.plus = function(a,b){console.log(a+b);},this.minus = function(a,b){console.log(a-b);}}//全部计算方法function FullCompute(){Compute.apply(this);//apply 更改了Compute 类的指向。//乘this.mul = function(){console.log(a*b);},//除this.div = function(){console.log(a/b);}}//实例化FullComputevar compute = new FullCompute();compute.plus(1,2);//3compute.minus(1,2);//-1compute.mul(1,2);//2compute.div(1,2);//0.5
demo
年龄为多少岁姓名为xx买了一辆排量为xx的什么颜色,什么牌子的汽车。
//Person的构造函数。function Person(opt){Car.call(this,opt.carOpt);//这里借用了Car 修改了car的this指向。此时this指向实例化对象。this.name = opt.name;this.age = opt.age;this.speak = function(){console.log(this.name +''+this.age +'岁 '+'买了一辆排量为'+this.dispatchment+this.color+'颜色的'+this.brand+'汽车')}}//Car的构造函数function Car(opt){this.color = opt.color;this.brand = opt.brand;this.dispatchment = opt.dispatchment}//实例化Personvar p = new Person({name:'张三',age:30,carOpt:{color:'red',brand:'Benz',dispatchment:'3.0T'}});console.log(p)//{name:'张三',age:30,color:'red',brand:'Benz'}p.speak();
