一、原型:是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);//打印结果为呵呵呵。证明调用的是toString3、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课程" ,一个值得推荐的"渡一教育"。