面向对象的几种创建方式
字面量创建
//字面量创建
var obj = {
name:"李四",
age:21,
hoddy:function()
{
console.log("学习");
}
}
var obj2 = {
name:"张三",
age:12,
hobby:function()
{
console.log("唱歌");
}
}
console.log(obj);//{name: "李四", age: 21, hoddy: ƒ}
console.log(obj2);//{name: "张三", age: 12, hobby: ƒ}
//适合创建单个对象,创建多个容易造成代码冗余
2.实例化创建 也叫单例创建
//实例创建也叫作单例创建使用new关键字创建
var obj1 = new Object();
obj1.name = "张三",
obj1.age = 21,
obj1.hobby = function()
{
console.log("学习");
}
var obj2 = new Object();
obj2.name = "李四",
obj2.age = 23,
obj2.hobby = function()
{
console.log("唱歌");
}
//缺点: 也只适合创建单个对象 ,容易造成代码的冗余
3.工厂模式创建
//工厂模式 批量生产对象
function createObj(name,age,hobby)
{
//原料
var obj = new Object();
//加工
obj.name = name;
obj.age = age;
obj.hobby = hobby;
//出厂
return obj
}
var obj1 = createObj("小明",21,"敲代码");
console.log(obj1);//{name: "小明", age: 21, hobby: "敲代码"}
var obj2 = createObj("小红",18,"唱歌");
console.log(obj2);//{name: "小红", age: 18, hobby: "唱歌"}
var obj3 = createObj("cat",3,"吃鱼");
console.log(obj3); //{name: "cat", age: 3, hobby: "吃鱼"}
//缺点: 虽然解决了代码冗余问题(可以创建多个对象) 但是不能区分他们具体是什么类型 比如小明小红都是人,小猫是动物
4.构造函数
//构造函数一般函数名首字母要大写这是为了区分普通函数
//构造函数里面不需要自己创建对象 只需要在this上添加属性和方法
//构造函数前面必须加new 否则会和普通函数一样
function Student(name,age,hobby)
{
this.name = name;
this.age = age;
this.hobby=hobby;
}
var stu = new Student("张三",21,"打游戏");
console.log(stu);//Student {name: "张三", age: 21, hobby: "打游戏"} 这样可以区分具体的类
//new 操作符的作用(可以对比着工厂模式创建)
//1.隐式创建了一个空对象,并让this指向这个空对象 this = new Object() 相当于这一步省略了
//2.执行构造函数中的代码 this上添加属性以及方法
//3.将创建的实例对象的__proto__指向构造函数的prototype
//4.并将这个隐式的对象返回(隐式对象中添加了属性以及方法) return this; 因为this指向的是那个对象
//如果将new关键字去掉Student是一个普通函数
// var stu1 = Student("小李",23,"唱歌");
// console.log(stu1);
// console.log(stu1.age);
//虽然相比这个工厂模式是解决了对象明确问题
//但是会浪费内存(因为每次都隐式的创建一个对象 都会开辟一块儿新的内存)浪费资源
在这里简单说一下 原型对象和原型属性的概念
//原型对象和原型树形
// prototype 原型对象 :函数在声明的时候会自动创建一块儿存储空间,用于存储公共的共享属性和方法,prototype中的construct指向该函数
//__proto__ 原型属性,每一个实例对象在创建的时候都会有一个原型属性__proto__会指向构造函数的prototype
function sum()
{}
console.dir(sum)
var arr = new Array();
console.dir(arr);
console.log(arr.__proto__ === Array.prototype); //true
5 原型创建
function Student(){};
Student.prototype.SameHobby = "学习";
Student.prototype.SameFunc = function()
{
console.log("吃零食");
}
var stu1 = new Student();
console.log(stu1)
// Student {}
// __proto__:
// SameFunc: ƒ ()
// SameHobby: "学习"
// constructor: ƒ Student()
// __proto__:
//缺点: 解决了资源浪费问题 但是实例的时候不能传递参数
6 混合创建
//混合创建 构造函数(可变) 原型(固定,公共,共享的)
function Student(name,age)
{
this.name = name;
this.age = age;
this.func = function()
{
console.log("敲代码")
}
}
Student.prototype.hobby = "学习";
Student.prototype.skill = function()
{
console.log("学习");
};
var stu1 = new Student("张三",21);
console.log(stu1);
//特点:实例化对象有自己的一些属性和方法,Student的公共属性和方法放置在prototype中
动态混合创建
//动态混合创建
function Student(name, age, skill) {
this.name = name;
this.age = age;
this.skill = skill;
if (typeof this.study != "function") {
Student.prototype.school = "高中";
Student.prototype.study = function() {
console.log("学习");
}
}
}
var student1 = new Student("张三", 18, "学习");