类的创建
使用构造函数创建对象
构造函数是一种特殊的函数,主要用于初始化对象,一般与new
关键字配合使用new
在执行时,首先创建一个对象,将this指向这个对象,然后执行构造函数的代码,给这个对象添加属性和方法并返回这个对象,所以构造函数不需要return
function Person(name,age){
this.name = name;
this.age = age;
this.say =function hello(){
console.log(name);
}
}
let m = new Person("小明",18);
m.say();
构造函数
构造函数中可以添加一下成员与方法,也可以在构造函数本身上添加,通过这两种方式添加的成员,就分别称为静态成员和实例成员
- 静态成员
在构造函数本身上添加的成员称为静态成员,只能由构造函数本身来访问
Person.kind = "人类";
- 实例成员
在构造函数内部创建的对象成员称为实例成员,只能由实例化的对象来访问
let m = new Person("小明",18);
m.say();
但是构造函数在创建对象时,会给所有方法创建开辟内存空间,造成内存的浪费
let m = new Person("小明",18);
let s = new Person("a",20);
console.log(s.say ===m.say);// false
在ES6中,创建对象可以用class关键字
class Person {
constructor(name ,age){
this.name = name;
this.age = age;
}
say(){
console.log(this.name);
}
}
let person = new Person("ming",18);
person.say();
原型
构造函数原型 prototype
构造函数通过原型分配的函数是所有对象共享的,JavaScript中每个构造函数都有一个prototype属性,指向另一个对象,prototype是一个对象,这个对象所有的属性和方法,都会被构造函数所拥有。可以把那些不变的方法,直接定义在prototype对象上,这样所有的对象可以共享这些方法。
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.say=function(){
console.log(this.name);
}
let person= new Person("xiao",18);
let person1= new Person("da",18);
person.say();//xiao
console.log(person.say ===person1.say);//true
对象原型 proto
对象都会有一个属性__proto__指向构造函数的prototype原型对象,之所以对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型存在
- __proto__对象原型和原型对象prototype是等价的
- __proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是他是一个非标准属性,因此实际开发中,不可以使用这个属性。
console.log(person.__proto__.say===Person.prototype.say);//true
同时原型对象持有一个constructor指向构造函数
console.log(Person.prototype.constructor === Person);//true
原型链
Person原型对象prototype也有__proto__对象,这个对象指向的是Object.prototype。而该对象的对象原型指向则是null,这样,就构成了一条原型链
成员查找按照原型链查找
- 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性
- 如果没有就查找他的原型,即__proto__指向的prototype原型对象。
- 如果还没有就查找原型对象的原型(Object的原型对象)
- 以此类推一直找到null为止
- __proto__对象原型的意义就在于为对象成员查找机制提供了一个方向,或者说一条路线
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.length = "100";
Object.prototype.width = "200";
let person = new Person("ming",18);
console.log(person.age);//18
console.log(person.length);//100
console.log(person.width);//200
类的继承
ES6之前并没有extends继承,我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承
call()
调用这个函数,并且修改函数运行时的this指向
fun.call(thisArg,arg1,arg2,...)
- thisArg:当前调用函数this的指向对象
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.say=function(){
console.log(this.name);
}
let person= new Person("小明",18);
let person1= new Person("大熊",18);
person.say();//小明
person.say.call(person1);//大熊
借用构造函数继承父类属性
通过call()把父类型的this指向子类型的this,这样就可以实现子类型继承父类型的属性
function Father(name,age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name);
}
}
function Son(name,age,sex){
Father.call(this,name,age);
this.sex = sex;
}
let son = new Son("大熊",18,"男");
console.log(son.name,son.age,son.sex);//大熊 18 男
son.say();//大熊
console.log(son);//Son { name: '大熊', age: 18, say: [Function], sex: '男' }
还可以通过修改原型对象的方式,来添加原型链,从而获得父类方法
//此处不能直接指向Father的原型对象,否则在修改Son.prototype时,会改变父类的原型对象
Son.prototype = new Father();
Son.prototype.constructor = Son;
let son = new Son("小明",18,"男");
son.say();//小明
ES6类的继承
class Father{
money(){
console.log(100);
}
}
class Son extends Father{
}
let son = new Son();
son.money();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。