目录
1 引入构造函数
2 通过构造函数创建对象-内置
3 自定义一个构造函数来创建对象
3.1 构造函数的概念
3.2关于new Object()
3.3 构造函数的执行过程
3.3.1构造函数的返回值
3.3.2 如何判断一个数据是否是复杂数据类型?
3.3.3为什么要理解构造函数的返回值?
3.3.4如何分辨出一个对象是不是某个构造函数的实例?
1 引入构造函数
通过创建多次单个对象,存在问题如下:
a、存在很多冗余代码
b、所有的对象都有say方法,并且功能相似,但是他们占据了不同的内存-->会导致内存浪费(内存泄漏)<script> var p1 = { age: 100, gender: "女", say: function () { } } var p2 = { age: 100, gender: "女", say: function () { } } var p3 = { age: 100, gender: "女", say: function () { } } var p4 = { age: 100, gender: "女", say: function () { } } var p5 = { age: 100, gender: "女", say: function () { } } var p6 = { age: 100, gender: "女", say: function () { } } </script>
使用构造函数进行优化,使代码整洁了许多!!
<script> //构造函数 function Person(age, gender) { this.age = age; this.gender = gender; //此时的say方法内存依然浪费了-->原型(解决方法,后面展开) this.say = function () { } } //使用这种方式创建对象,代码整洁了很多 var p1 = new Person(5, "未知"); //Person是p1的构造函数 var p2 = new Person(5, "未知"); var p3 = new Person(5, "未知"); var p4 = new Person(5, "未知"); var p5 = new Person(5, "未知"); var p6 = new Person(5, "未知"); //还有一个遗留问题(在后续继承中展开) </script>
2 通过构造函数创建对象-内置
构造函数创建对象的例子:
+ var xiaoming = new Object() --> (等价于) var xiaoming = {};
+ var now = new Date()
+ var rooms = new Array(1,3,5) --> var rooms = [1,3,5]
+ `var isMale=/123/;` ==> `var isMale=new RegExp("123")`
- isMale是通过RegExp构造函数创建出来的对象
- isMale是RegExp构造函数的实例+ 以上例子中,Object、Date、Array都是内置的构造函数
3 自定义一个构造函数来创建对象
+ 构造函数
```js
function Person(name,age){
this.name=name;
this.age=age;
}
var p1=new Person("张三",18)
```
+ 说明:`p1就是根据【Person构造函数】创建出来的对象`
3.1 构造函数的概念
构造函数的概念
+ 任何函数都可以当成构造函数,都可能称为构造函数
`function CreateFunc(){ }`
+ 只要把一个函数通过new的方式来进行调用,我们就把这一次函数的调用方式称之为:构造函数的调用
- new CreateFunc(); 此时CreateFunc就是一个构造函数
- CreateFunc(); 当成普通函数使用,此时的CreateFunc并不是构造函数
3.2关于new Object()
+ new Object()等同于对象字面量{}
在JavaScript中,
new Object()
和 对象字面量{}
确实在功能上非常相似,它们都用于创建一个新的对象实例。然而,从语法、性能和日常使用的角度来看,它们之间有一些细微的差别。
语法:
new Object()
:这是使用构造函数创建一个新对象的传统方式。{}
:这是使用对象字面量语法创建一个新对象的更简洁、更现代的方式。性能:
- 在现代JavaScript引擎中,两者在性能上的差异几乎可以忽略不计。然而,由于对象字面量语法更简洁,它可能稍微快一点,因为解析器需要处理的字符更少。
可读性:
- 对象字面量语法通常更受欢迎,因为它更简洁、更易于阅读和维护。
- 使用
new Object()
在某些情况下可能会使代码看起来更加冗余或过时。初始化属性:
- 使用对象字面量语法,你可以在创建对象的同时初始化其属性。例如:
let obj = {a: 1, b: 2};
- 使用
new Object()
,你通常需要在之后单独设置对象的属性。例如:let obj = new Object(); obj.a = 1; obj.b = 2;
扩展性:
- 如果你正在使用ES6或更高版本的JavaScript,并且希望利用类的继承和其他面向对象的特性,那么使用类(通过
class
关键字)和new
关键字可能更有意义。然而,这并不直接适用于new Object()
与对象字面量之间的比较。特殊情况:
- 当你需要在函数中返回一个新对象,但该函数还没有返回任何内容时,使用
new Object()
可能是有意义的,因为你可以通过链式调用在对象上立即设置属性或方法。但是,这通常可以通过使用对象字面量语法和IIFE(立即调用的函数表达式)来实现更简洁的代码。总的来说,尽管
new Object()
和 对象字面量{}
在功能上是相似的,但对象字面量语法通常更受欢迎,因为它更简洁、更易于阅读和维护。在大多数情况下,你应该优先使用对象字面量语法来创建新的对象实例。
3.3 构造函数的执行过程
`var p1=new Person();`
+ 1、创建一个对象 (我们把这个对象称之为Person构造函数的实例)- `_p1 `
+ 2、创建一个内部对象,`this`,将this指向该实例(_p1)
+ 3、执行函数内部的代码,其中,操作this的部分就是操作了该实例(_p1)
+ 4、3.3.1构造函数的返回值
- a、如果函数没有返回值(没有return语句),那么就会返回构造函数的实例(p1)
- b、如果函数返回了一个基本数据类型的值,那么本次构造函数的返回值是该实例(_p1)
//无返回值 function fn(){ } var f1=new fn(); //f1就是fn的实例 //基本类型值 function fn2(){ return "abc"; } var f2=new fn2(); //f2是fn2构造函数的实例
- c、如果函数返回了一个复杂数据类型的值,那么本次函数的返回值就是该值
function fn3(){ return [1,3,5]; //数组是一个对象类型的值, //所以数组是一个复杂数据类型的值 //-->本次构造函数的真正返回值就是该数组 //-->不再是fn3构造函数的实例 } var f3=new fn3(); //f3还是fn3的实例吗?错 //f3值为[1,3,5]
3.3.2 如何判断一个数据是否是复杂数据类型?
使用排除法:
a、看它的值是不是:数字、字符串、布尔值、null、undefined,
b、如果不是以上5种值,那就是复杂数据类型
发杂数据类型举例:
- [1,3,5]
- /abc/
- function(){}
- new Object();
3.3.3为什么要理解构造函数的返回值?
String是一个内置函数
a、String()
b、new String()
结论:一个函数通过new调用,或者不通过new调用,很多时候会有截然不同的返回值
3.3.4如何分辨出一个对象是不是某个构造函数的实例?
a、var isTrue=xxx instanceof Person
function Person(){ } var p1=new Person(); console.log(p1 instanceof Person);//true,就是Person的实例 function Student(){ return 100; } var s1=new Student(); console.log(s1 instanceof Student);//true,就是Student的实例 function Programmer(){ return [1,3,5] } var pro=new Programmer();//pro并不是Programmer的实例 console.log(pro instanceof Programmer);//false console.log("是数组的实例吗?",pro instanceof Array);//true
小技巧:如何通过肉眼识别xxx对象是哪个构造函数的实例?
xxx.__proto__属性(Prototype),也是对象,该对象中一般都会有一个constructor属性,这个指向aaa函数,那么就可以认为:xxx是aaa构造函数的实例
typeof运算符,只能判断:数字、字符串、布尔值、undefined、函数
切记:千万不能使用typeof运算符来判断对象的构造函数
- typeof null === "object"
- typeof {} === "object"
- typeof [] === "object"
- typeof function(){} === "function"
- typeof /abc/ === "object"