js原型、原型链、call apply
原型
1.定义:原型是function对象的一个属性,它定义了构造函数构造出的对象的共同祖先,通过这个构造函数创建的对象可以继承该原型的属性和方法。原型也是对象。
2.利用原型的特点和概念,可以提取共有属性。
3.对象如何查看原型:隐式属性 .proto
4.对象如何查看对象的构造函数:.constructor, 可以手动更改
function Person(){
}
car.prototype = {
made:"china",
price:2300000
}
car.prototype.name = "BWM"; //新增原型属性
car.prototype.year = 2018;
function car(color,owner){
this.color = color;
this.owner = owner;
}
var car1 = new car("red","chen");
var car2 = new car("green","li");
console.log(car1.constructor);//function car(){};
car.prototype.constructor = Person();
console.log(car1.constructor);//function Person(){};
原型链
- 如何构成原型链
grand.prototype.__prototype__ = Object.proto
grand.prototype.lastname = "chen";
function grandtype;
}
var grand1 = new grand();
father.prototype = grand;
function father(){
this.name = "ying";
this.forturn = {
card1 :"visa"
}
}
var fa1 = new father();
son.prototype = fa1;
function son(){
this.name = 'jie';
this.age = 18;
}
var son1 = new son();
- 原型链上的增删改查
- 后代不能增删改原型链上祖先的属性
son1.forturn.card2 = "china";
//可以添加这个属性是因为,son1在这调用了forturn,引用值forturn可以添加属性。
//但是son.prototype.wife = "hehe";可以给son.prototype添加属性wife,但是son原来的原型father上不会添加wife属性。
- 查询属性
先在自己的属性里面找,如果没有就到原型上找,如果没有再往原型的原型上找,以此类推,知道原型链尽头(Object.prototype).
PS:谁调用的方法,里面的this就指向谁。
Person.prototype = {
name:"a",
sayName:function (){
console.log(this.name);
}
}
function Person() {
this.name = "b";
}
var p = new Person();
p.sayName();//b
-
绝大多数对象最终都会继承自Object.prototype
例外:一切对象的原型是一个对象或者null,所以不是所有对象的最终都会继承自Obeject.prototype.
Object.create(null); -
Object.create方法
// var obj = Object.create(原型);//原型归类
var obj = {name:"chen", age:12};
var obj1 = Object.create(obj);
Person.prototype.name = "sunny";
function Person(){
}
var person = Object.create(Person.prototype);//
PS: undedinefed,null是原始值,且不能进行包装类,所以它们没有toString()方法。
call/apply
作用:改变this 指向
- call
function Person(name,age){
this.name = name;
this.age = age;
}
var person = new Person("chen",18);
var obj = {};
Person.call(obj,"li",20);//this指向obj,第一个参数代表指向的对象,后面的参数对应到函数的参数。
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name,age,sex,tel,grade){
Person.call(this,name,age,sex);//调用别的函数实现自己的功能。
this.tel = tel;
this.grade = grade;
}
var student = new Student('sunny',123,'male',139,2017);
2.apply
作用:改变this指向
与call的不同:传参列表不同。call需要把实参按照形参的个数传进去。apply需要传一个arguments。
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name,age,sex,tel,grade){
Person.apply(this,[name,age,sex]);//apply传进的参数为一个数组
this.tel = tel;
this.grade = grade;
}
var student = new Student('sunny',123,'male',139,2017);
bzoj2882 工艺
bzoj3097 Hash Killer I
bzoj3729 Gty的游戏
【BZOJ4555】[TJOI&HEOI2016]求和 斯特林数+NTT
【bzoj4869】[Shoi2017]相逢是问候 线段树+扩展欧拉定理
【BZOJ1853】[Scoi2010]幸运数字 容斥原理+搜索
【BZOJ2839】集合计数 容斥原理+组合数
【BZOJ3622】已经没什么好害怕的了 容斥原理+dp
【BZOJ3589】动态树 树链剖分+线段树