Appearance
构造函数模式
基于构造函数创建自定义类(constructor)
- 在普通函数执行的基础上"new xxx()",这样就不是普通函数执行了,而是构造函数执行,当前的函数名称之为“类名”,接收的返回结果是当前类的一个实例
- 自己创建的类名,最好第一个单词首字母大写
- 这种构造函数设计模式执行,主要用于组件、类库、插件、框架等的封装,平时编写业务逻辑一般不这样处理
javascript
function Fn() {}
Fn(); // => 普通函数执行
var f = new Fn(); // => Fn是类 f是类的一个实例
var f2 = new Fn(); // => f2也是Fn的一个实例,f2和f是独立分开的,互不影响
1
2
3
4
2
3
4
JS 中创建值有两种方式
- 字面量表达式
javascript
var obj = {};
1
- 构造函数模式
javascript
var obj = new Object();
1
不管是哪一种方式创造出来的都是 Object 类的实例,而实例之间是独立分开的,所以 var xxx={} 这种模式就是 JS 中的单例模式
创建基本类型
基本数据类型基于两种不同的模式创建出来的值是不一样的
- 基于字面量方式创建出来的值是基本类型值
javascript
var num1 = 12;
console.log(typeof num1); // => "number"
1
2
2
- 基于构造函数创建出来的值是引用类型
javascript
var num2 = new Number(12);
console.log(typeof num2); // => "object"
1
2
2
函数的执行
javascript
function Fn(name, age) {
var n = 10;
this.name = name;
this.age = age + n;
}
1
2
3
4
5
2
3
4
5

普通函数的执行
javascript
Fn();
1
- 形成一个私有的作用域
- 形参赋值
- 变量提升
- 代码执行
- 栈内存释放问题
构造函数执行
javascript
var f1 = new Fn("xxx", 20);
var f2 = new Fn("aaa", 30);
console.log(f1 === f2); //=> false:两个不同的实例(两个不同的堆内存地址)
console.log(f1.age); // => 30
console.log(f2.name); // => 'aaa'
console.log("name" in f1); // => true name&age在两个不同的实例都有存储,但是都是每个实例自己私有的属性
console.log(f1.n); // => undefined 只有this.xxx=xxx的才和实例有关系,n是私有作用域中的一个私有变量而已(this是当前类的实例)*/
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
构造函数执行,不写 RETURN
构造函数执行,不写 RETURN,浏览器会默认返回创建的实例,但是如果我们自己写了 RETURN?
return 是的一个基本值,返回的结果依然是类的实例,没有受到影响
如果返回的是引用值,则会把默认返回的实例覆盖,此时接收到的结果就不在是当前类的实例了 => 构造函数执行的时候,尽量减少 RETURN 的使用,防止覆盖实例
javascript
function Fn() {
var n = 10;
this.m = n;
// return;//=>这样 RETURN 是结束代码执行的作用,并且不会覆盖返回的实例
// console.log(1);
}
var f = new Fn(); //=> new Fn; 在构造函数执行的时候,如果 Fn 不需要传递实参,我们可以省略小括号,意思还是创建实例(和加小括号没有区别)
console.log(f);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8