JavaScript不区分类和实例的概念,是通过原型(prototype)来实现面向对象编程
类:类是对象的类型模板,比如定义Student类来表示学生,但它不表示任何具体的学生
实例:实例是根据类创建的对象,比如根据Student类,可以创建出"小明","小花"等多个
实例,每一个实例代表一个学生,这些实例全部属于Student类
创建一个对象:
var obj = new Object();//obj就是new Object的实例
obj.name = "小明";//静态的是属性
obj.age = 18;
obj.run = function(){//动态的是方法
return this.name+this.age+"在跑步。。。";
this用在对象里面,指向的是对象的实例
}
console.log(typeof obj,obj);//object {name: "小明", age: 18, run: ƒ}
console.log(obj.run());//小明18在跑步。。。
工厂模式:
为了解决多个类似对象声明的问题,也是为了解决实例化对象产生大量代码重复的问题
function createObj(name,age){
var obj1 = new Object();//obj就是new Object的实例
obj1.name = name;//静态的是属性
obj1.age = age;
obj1.run = function(){//动态的是方法
return this.name+this.age+"在跑步。。。";
// this用在对象里面,指向的是对象的实例
}
return obj1;
}
var create_obj = createObj("小花",18);
var create_obj01 = createObj("小红",19);
console.log(create_obj,create_obj01);
//{name: "小花", age: 18, run: ƒ} {name: "小红", age: 19, run: ƒ}
console.log(create_obj instanceof createObj);//false
工厂模式的问题:
1.创建不同的对象,其中的属性和方法都会重复创建,消耗内存
2.会产生函数识别的问题
注意事项:
1.用函数将所有内容都打包起来,按照需求传入形参
2.函数内部必须返回该函数
构造函数:
构造函数的方法的规范:
1.函数名和实例化构造名相同且大写(非强制性,这么写有助于区分构造函数和普通函数)
2.通过构造函数创建的对象,必须要使用关键字new
构造函数和普通函数的区别:
使用关键字new的是构造函数,没有关键字new的是普通函数
function Obj(name,age){
this.name = name;
// this代表当前作用域对象的引用,如果在全局范围,指向的是window对象,
// 如果在构造函数体内,指向的是构造函数所声明的对象
this.age = age;
this.run = function(){
return this.name+this.age+"在跑步。。。";
}
}
var obj2 = new Obj("小黑",30);
var obj3 = new Obj("小乌龟",99);
//当使用了 new 构造函数方法,就会在后边执行new Object
console.log(obj2,obj3);//{name: "小黑", age: 30, run: ƒ} Ojb {name: "小乌龟", age: 99, run: ƒ}
console.log(obj2.run());//小黑30在跑步。。。
console.log(obj3.run());//小乌龟99在跑步。。。
console.log(obj3 instanceof Obj);//true 解决了对象识别问题
console.log(obj2 === obj3);//false
同一个构造函数的实例之间无法共享属性和方法
构造函数解决了工厂模式遗留的函数识别问题,没有解决内存消耗的问题,
同时还带了新的this指向的问题
构造函数创建对象的执行过程:
1.当使用了构造函数,并且使用 new 构造函数(),就会在后台执行 new Object()
2.将构造函数的作用域指给新的对象(也就是通过 new Object()创建出来的实例),函数体内的this就代表当前被创建出来的实例
3.执行构造函数体内的代码
4.返回新对象
原型(prototype)
function Student(name,age){
this.name = name;
this.age = age;
}
Student.prototype.run = function(){//公共方法.原型对象上的所有属性和方法,都是可以被对象实例所公用的
return this.name+this.age+"在睡觉。。。";
}
var stu01 = new Student("小白",20);
var stu02 = new Student("大白",21);
stu01.run = function(){//私有方法
return this.name+this.age+"在做梦";
}
console.log(stu01.run());//小白20在做梦。。。 若有私有方法 会先调用私有再去调用公共
console.log(stu02.run());//大白21在睡觉。。。
console.log(stu01.run === stu02.run);//true
原型对象的作用,就是定义所有对象的实例所共享的属性和方法;
prototype对于构造函数来说它是一个属性,对于对象实例来说,它是一个原型对象
原型解决了内存消耗的问题和this指向的问题
原型(prototype)
js中除了undefined 和 null ,其他的数据类型都是有对象的,每一个对象都继承另外一个对象
后者被称为原型(prototype)对象,null是没有自己的原型对象的
原型对象上的所有属性和方法,都是可以被对象实例所公用的
__ proto __:
对象的内置属性,用于指向创建它的函数对象的原型对象的prototype
console.log( stud01.__proto__ === Stu.prototype );//true
console.log(stud01.__proto__,Stu.prototype);//指向一样 {total: ƒ, constructor: ƒ} {total: ƒ, constructor: ƒ}
Stu.prototype对象也有__proto__(内置属性), 指向Object.prototype
console.log(Stu.prototype.__proto__);
原型链:
原型对象本身也是对象,它也有自己的原型,而它自己的原型对象又可以有自己的原型
这样就组成一条链,这个就是原型链
实例对象的proto指向的是构造函数的原型
构造函数原型的proto指向的是Object的原型
Object原型的proto指向null
网友评论