在学习了面向对象,咱们了解了面向对象的三大特性:封装、继承、多态。下面咱们须要了解对象的建立方式:css
对象有不少描述方式,好比键值对(key--value)的集合、字典、工具包。对象的本质是对变量和函数进行封装,将变量封装成属性,函数封装为方法;这里咱们就是采用字典的方式来建立对象,将属性和方法名做为keyhtml
var book = { name:"js入门教学", price:"¥34", author:"刘忻欢", showName: function () { console.log(this.name); } } /*调用对象 */ console.log(book.name);
特色:字面量建立方式比较简单,把方法和属性写在{}中,可是当须要建立多个同类型的对象的时候,代码的重复性就比较高,它不适用于批量的建立同类型的对象。函数
var book1 = { name:"js入门教学", price:"¥34", author:"刘忻欢", showName: function () { console.log(this.name); } } var book2 = { name:"html+css深刻浅出", price:"¥50", author:"张某某", showName: function () { console.log("jjjj"); } }
js内置构造函数有:Object Function Date String Number Array .....工具
建立方式分为两步:性能
/*首先 建立一个空对象*/ var obj = new Object(); /*其次 设置属性|方法*/ obj.name="内置构造函数建立对象"; obj.ways = function () { console.log("2步"); }
特色:利用内置构造函数建立对象和字面量方式建立同样,须要建立多个同类型的对象时,会出现大量重复的代码。学习
3.1 建立书的工厂函数this
function createBook(name,author,price){ /*建立一个空对象*/ var book = new Object(); book.name = name; book.author = author; book.price = price; book.log = function () { console.log("eee"); } return book; }
3.2 建立多个书对象spa
var book1 =new createBook("三毛流浪记","张乐平","南方出版社"); // 打印书名 console.log(book1.name); var book2 = new createBook("阿衰","猫小乐","云南出版集团公司"); // 打印book2对象 console.log(book2);
特色:① 利用工厂函数建立对象,只要经过 new 函数() 就能够建立出不一样的对象 。prototype
② 可是有多个工厂函数,且属性和方法相同时,建立出来的对象就没法识别对象的类型,由于建立对象都是使用Object的原生构造函数来完成的。3d
3.3 多个工厂函数
function createPerson(name,age,eating){ var person = new Object(); person.name = name; person.age = age; person.eat = function () { console.log(eating); }
return person; } function createDog(name,age,eating){ var dog = new Object(); dog.name = name; dog.age = age; dog.eat = function () { console.log(eating); }
return dog; }
构造了建立人和狗的两个方法,他们的属性和方法同样
var person1 = new createPerson("小明","23","吃米饭"); var dog1 = new createDog("小小明","2","狗粮"); console.log(person1); console.log(dog1);
打印结果:
问题:咱们没办法区分哪一个对象是 createPerson方法建立 ,哪一个是createDog 方法建立
总结:为何将这种方式叫作工厂呢,由于它的模式和工厂十分类似。工厂的特色:批量生产(原料 --- 加工 --- 产品)
什么是构造函数:① 构造函数和普通函数本质上没有区别
② 构造函数一般首字母大写(这是为了 人为的区分)
③ 在调用时,构造函数必需要和 new关键字 结合
① 提供一个构造函数
② 在构造函数内部经过 this 设置属性和方法
③ 经过 new 函数() 建立对象
/*1 提供一个构造函数*/ function Person(){ /* 2 在函数内部经过 this 设置属性和方法*/ this.name = "张三"; this.age = 23; this.sex ="男"; } /*3 经过 new 函数() 来建立对象*/ var zhangsan =new Person(); console.log(zhangsan);
自定义构造函数建立对象须要咱们完成的核心过程就这三步,可是其内部默认完成的工做其实复杂的多:
内部实现细节:
① 默认在内部会建立一个空的对象 var o = new Object();
② 默认会把新建立的对象赋值给 this this = o;
③ 默认会设置新建立的对象的原型对象为当前的原型对象 o.prototype = Person.prototype;
④ 默认会设置新建立对象的构造器属性为当前构造器属性 o.constructor = Person
⑤ 经过 this设置属性和方法(这是咱们本身完成的操做)
⑥ 默认会返回新建立的对象 return o;
注意点:
Ⅰ.若是咱们没写 return ,那么默认返回新建立的对象
Ⅱ. 若是咱们写了 return:
ⅰ.若是返回的是值类型(null | undefined | "string" | number...),那么咱们本身写的 return 语句会被忽略,返回的仍然是新建立的对象;
ⅱ. 若是返回的是引用类型,那么就会直接返回 咱们写的 renturn 后面的对象,而内部默认建立的 return 会被忽略。
当返回数值类型:
/*1 提供一个构造函数*/ function Person(){ /* 2 在函数内部经过 this 设置属性和方法*/ this.name = "张三"; this.age = 23; this.sex ="男"; return "zzzzz; } /*3 经过 new 函数() 来建立对象*/ var zhangsan =new Person(); console.log(zhangsan);
输出结果:
当返回引用类型:
/*1 提供一个构造函数*/ function Person(){ /* 2 在函数内部经过 this 设置属性和方法*/ this.name = "张三"; this.age = 23; this.sex ="男"; return Array("zhang",1,3,6); } /*3 经过 new 函数() 来建立对象*/ var zhangsan =new Person(); console.log(zhangsan);
输出结果:
function Person(name,age,eating){ this.name = name; this.age = age; this.eat = function(){ console.log(eating); } } function Dog(name,age,eating){ this.name = name; this.age = age; this.eat = function(){ console.log(eating); } } var person1 =new Person("张撒",23,"食物"); var dog1 =new Dog("阿黄",2,"狗粮"); console.log(person1); console.log(dog1); /* 采用类型判断*/ console.log(person1 instanceof Person); console.log(dog1 instanceof Dog);
输出结果:
注意点:全部的对象都是Object类型,所以全部对象 obj1 instanceof Object 的返回值都是true.
总结:
自定义构造函数建立对象可以区分对象的类型
function Person(name,age,sex){ this.name = name; this.age = age; this.sex =sex; this.showName = function () { console.log(this.name); } } var person1 = new Person("zhangsan",23,"男"); var person2 = new Person("zhangsan",22,"女"); console.log(person1.showName ==person2.showName); //false person1.showName = function () { console.log("123"); } person1.showName(); //123 person2.showName(); //zhangsan
对代码建立对象结构分析以下:
总结:由输出结果以及结构分析,能够看出person1.showName 与 person2.showName 是不一样的,他们各占一个内存空间,这样当要建立大量的对象的时候,就会建立出大量一样的 方法,这样会浪费性能空间,那么如何让不一样的对象共享同一个方法呢?下一章我将为你们分析 采用原型对象解决方法共享问题。
eating