//Person.prototype ----原型 ? 一个对象 ? 当一个函数被定义时它就存在,自身带的属性
//Person.prototype = {} 是祖先
Person.prototype.Firstname = "li"
Person.prototypr.Lastname = "Am"
//或者
//Person.prototype = {
// Firstname: "li",
// Lastname:"Am"
//}
function Person (Lastname) {
? ?this.Lastname = Lastname;
}
var person = new Person(Bm);
var person1 = new Person(Cm);
console.log(person.Fiestname,person.Lastname);
//输出“li Bm”,虽然 new Person()之中没有name属性,但是它会从它的Person.prototype(原型)中继承,如果 new Person()中有该属性那么就会用自己的属性而不会用原型的属性。
console.log(person.Firstname,person.Lastname);//也是输出“li Cm”,以为它和person1用的是同一个原型;
比如上面中的Firstname就相当与公共属性,在原型中增加该属性可以减少耦合;
增删改
基本上只能通过函数的原型来修改(Person.protoype.Firstname = "wang").
通过new的对象来修改基本上不可能
查
只有被继承时才会显示
Person.prototype = {
? ?//看似为空,其实其中有两个隐式属性,为系统自设;
? ?/*constructor:Person(), ? 是构造出这个原型的函数---可以手动更改
? _proto_:object ? ? ? ? ? 详下一个*/
}
function Noething (){
? ?
}
Person.prototype.constructor = Noething//此时Person.prototype.constructor 为noething。
5.prototype.proto
function Car () {
? ?/*new 的全过程 --- 隐式过程
? var this = {
? __proto__:Car.prototype ? ? ---- 相当于起到联接原型的作用
? };
? .....(执行函数内容)
? return this*/
}
var car = new Car();
通过—proto—来联接原型,使其形成链
Grand.prototype.Lastname = "li";
function Grand () {
? ?
}
var grand = new Grand();
?
Father.prototype = grand;
function Father() {
? ?this.name = "Am";
? ?this.money = "20W";
? ?this.key = {
? ? ? ?key1:"200"
? };
}
var father = new Father();
?
Son.prototype = father;
function Son () {
? ?this.name = "Bm";
? ?this.age = 18;
}
var son = new Son();
//假如出现没有的属性会一层一层的往上寻找 son->Son.prototype.__proto__(father)->Father.prototype.__proto__(grand)->Grand.prototype.__proto__(Object)->Object.prototype.__proto__(null) ————终端
console.log(son.name)//输出“Bm”
console.log(son.money)//输出"20W"
console.log(son.Lastname)//输出“li”
?
//增删改查 ? ---其实与原型差不多
son.Lastname = "wu"//这里是son本身加了一个属性,而非将Grand的Lastname修改为"wu"----增删改一样也(换句话就是通过子代修改父代基本上不能实现)
?
//特例-----针对于引用值(方法的修改,而不是覆盖/赋值的修改)
son.key.key2 = "300"//这里就可以将Father.key添加一个key2 = "300"的属性,而son并没有该属性,因为对于调用应用值它操作的是它直接(简而言之就是son.key.key2这里只是在操做key这个对象,son.key是调用了key)
?
Man.prototype = {
? ?name: "Am",
? ?height: 100,
? ?say: function (){
? ? ? ?console.log(this.name);
? }
}
function Man (){
? ?this.name = "Bm";
? ?this.eat = function(){
? ? ? ?this.height ++;
? }
}
var man = new Man()
man.say();//输出“Bm”,方法中的this指向---谁调用的就指向谁
man.eat();//man中会添加一个height属性并且值为101,首先调用eat()后会执行this.height ++,因为man自身没有height所以就会继承原型的height并且++后添加到man中
// var obj = Object.create(原型) --------create()括号中只能填“对象”或者"null"
var obj = {
name: "li",
? ?age: 19
}
var obj1 = Object.create(obj);//此时obj1的原型为obj
?
?
//因为create()可以填null,所以导致其创建出的对象可能没有原型
var obj2 = Object.create(null);
//此时obj2没有原型;
作用:改变this指向
function Person (name, age) {
? ?this.name = name;
? ?this.age = age;
}
var person = new Person()
var obj = {
? ?
}
Person.call(obj,"wu",20);//改变this指向,相当于在Person函数中顶部新增(this = obj),而后面两个是传入的参数
//实际上: Person() === person.call()
//此时;obj = {
// name: "wu",
// age: 20
//}
function Person (age,name){
? ?this.name = name;
? ?this.age = age;
}
/*假如也有一个构造函数需要实现的功能包括了上面的构造函数,如:
function Student (age,name,socor) {
this.name = name;
this.age = age;
this.socor = socor;
}*/
//那么就可以用call的方法简化代码
function Student (age,name,socor) {
? ?Person.call(this,age,name);
? ?this.socor = socor;
}
var student = new Student;
?
apply其实与call差不多,只有一点区别
传参方式的不同
call:需要把实参按照形参的个数传进去
apply:传入的是一个arguments(实参列表)----数组
function Student (age,name,socor) {
? ?Person.apply(this,[age,name]);
? ?this.socor = socor;
}