一、原型:是function对象的一个属性,是构造函数制造出对象的公共祖先。通过该构造函数产生的对象,可以继承原型的属性和方法。原型也是对象。
提取公有属性:
//Person.prototype = {},生来就有,是person1,person2...的爹
Person.prototype = {
//constructor : Person,
lastName : 'James',
firstName : 'Lebron',
gender : 'male',
age : 36
}
function Person(club,score){
//var this = {
// __proto__ : Person.prototype(在person1访问属性时,如果自己身上没有,就会沿着__proto__的指向去找)
//}
this.club = club;
this.score = score;
//return this;
}
var person1 = new Person('Laker', 10000);
var person2 = new Person('Heat', 8000);
增:Person.prototype.wife = 'Laurel';
删:delete Person.prototype.lastName; 从person1下手是删不掉
改:Person.prototype.lastName = 'King'; 在person1身上是改不掉的,除非是引用值的调用式修改,详情看下文。
查:person1.lastName;
Person.prototype生来有constructor属性,指向Person(),可以手动更改。
其中person1可以通过person1.constructor找到构造它的函数Person()。
二、原型链:
//Grand.prototype.__proto__ = Object.prototype
//Grand.prototype.lastName = 'James';
function Grand(){}
var grand = new Grand();
Father.prototype = grand;
function Father(){
this.fisrtName = 'Lebron';
this.club = {
no1 : 'Heat',
no2 : 'Laker'
}
}
var father = new Father();
Son.prototype = father;
function Son(){
this.hobbit = 'basketball';
}
var son= new Son();
增删改查,类似原型增删改查
说到其中的改:son.club.no3 = 'Rocket'; 可以实现引用值的调用式修改。
1、另一种构造对象的方式:
var obj = Object.create(原型)
绝大多数对象的最终都会继承自Object.prototype(Object.create(null)是个例外)。
2、关于toString(),观察下列代码输出。
Object.prototype上本身含有toString方法,但输出形式是"[object Xxxxx]",为何数字,字符串,数组,布尔会输出不同形式?
123.toString();//会报错,首先识别成浮点型
var num = 123;
num.toString(); //返回"123"
var str = 'abc';
str.toString(); //返回"abc"
var arr = [1,2];
arr.toString(); //返回"1,2"
var obj = {};
obj.toString(); //返回"[object Object]"
拿数字举例,尽管Number.prototype.__proto__ = Object.prototype。但Number.prototype上有重写的toString方法,并不会调用Object.prototype本身的方法。同样:
String.prototype上有重写的toString方法
Array.prototype上有重写的toString方法
Boolean.prototype上有重写的toString方法
如何来证明呢?还记得初学JavaScript使用过的document.write。我们来看一下它的底层原理。
var obj = Object.create(null);
document.write(obj);//会报错
var obj = Object.create(null);
//因为此时的obj对象没有prototype,也不存在toString方法,我们为其手动添加。
obj.toString = function(){
return '呵呵呵';
}
document.write(obj);//打印结果为呵呵呵。证明调用的是toString
3、JavaScript小bug:0.14 * 100 = 14.000000000000002
是由于JavaScript精度不准造成的,正常计算的范围是小数点前后各16位。我们应该尽量避免小数操作,如果不能避免,可以使用Math.floor/Math.ceil。
三、call和apply,改变this指向,传参列表不同
function Person(name, age, gender){
//this == obj
this.name = name;
this.age = age;
this.gender = gender;
}
var person = new Person('James', 36, 'male');
var obj = {};
//Person(); === Person.call();
Person.call(obj, 'Lau', 128, 'male');
在开发过程中,想用别人的方法实现自己的功能怎么办,还用说,call它啊,参数第一位把填自己的对象。
如下列代码,想要借用上图Person的方法来实现自己的功能,可按照下列操作。
function Student(tel, grade){
//var this = {__proto__ : Student.prototype}
Person.call(this, name, age, gender);
this.tel = tel;
this.grade = grade;
}
var student = new Student('Jack', 128, 'male', 17600001234, 2019);
call和apply的唯一不同之处在于传参列表,apply的传参形式为arguments。
以上内容属二哥原创,整理自 "渡一教育Javascript课程" ,一个值得推荐的"渡一教育"。