对象创建
{}
对象字面量
工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
function createPerson(name, age, gender) { var obj = new Object(); obj.name = name; obj.age = age; obj.gender = gender; obj.sayName = function () { alert(this.name); }; return obj; }
var obj2 = createPerson("猪八戒", 28, "男"); var obj3 = createPerson("白骨精", 16, "女"); var obj4 = createPerson("蜘蛛精", 18, "女");
|
- 构造函数
- 构造函数需要使用
new
关键字来调用才有意义
- 以构造函数的形式调用时,
this
指向新创建的实例对象
- 静态成员是构造函数的属性和方法,通过构造函数访问:
Person.prototype
- 实例成员是实例化对象的属性和方法,通过实例化对象访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; this.sayName = function () { alert(this.name); }; }
var per = new Person("孙悟空", 18, "男"); var per2 = new Person("玉兔精", 16, "女"); var per3 = new Person("奔波霸", 38, "男");
function Dog() {}
var dog = new Dog();
|
浅拷贝、深拷贝
- 浅拷贝的推荐实现:
Object.assign
原型和原型链
__proto__
是非标准属性,建议使用 ES6 新增的 Reflect.getPrototypeOf
和 Object.setPrototypeOf
Function.__proto__
等于Function.prototype
处理原型链污染
- 检测
constructor
、__proto__
这些敏感键值
- 使用
Object.create(null)
创建原型为null
的对象,保证对原型的修改无效
- 使用
Object.freeze()
冻结对象
- 建立 JSON schema ,在解析用户输入内容时,通过 JSON schema 过滤敏感键名
- 规避不安全的递归性合并
原型链继承
原型链继承->组合继承->寄生组合继承。
原型链继承
通过修改子类构造函数原型为父类构造函数实例实现。
存在的问题:
- 在创建子类实例的时候,不能向超类型的构造函数中传递参数
- 这样创建的子类原型会包含父类的实例属性,造成引用类型属性同步修改的问题
组合继承
使用call
在子类构造函数中调用父类构造函数解决原型链继承的问题。
存在的问题:
- 父类的构造函数被调用了两次(创建子类原型时调用了一次,创建子类实例时又调用了一次),导致子类原型上会存在父类实例属性,浪费内存
寄生组合继承
使用 Object.create(Parent.prototype)
创建一个新的原型对象赋予子类从而解决组合继承的缺陷。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
function Parent(value) { this.value = value; }
Parent.prototype.getValue = function () { console.log(this.value); };
function Child(value) { Parent.call(this, value); }
Child.prototype = Object.create(Parent.prototype, { constructor: { value: Child, enumerable: false, writable: true, configurable: true, }, });
const child = new Child(1); child.getValue(); child instanceof Parent;
|
继承关系判断
instanceof
instanceof
本质上是通过原型链查找来判断继承关系的,因此只能用来判断引用类型,对基本类型无效。
Object.prototype.isPrototypeOf