面向对象
构造函数
通过new创建对象的函数:new Person()
,Person
为构造函数
new 过程发生了什么
function _new(func){
// 1,创建一个新对象
const newObj = {};
// 2,将构造函数的作用域赋给新对象(因此this就指向了这个对象)
newObj.__proto__= func.prototype;
// 3,执行构造函数中的代码(为这个新对象添加属性);
func.call(newObj);
// 4,返回新对象
return newObj
}
new的原理是使用构造方法构造一个新的对象 结果是:
- 新对象的
__proto__
指向构造它的构造函数的原型:func.prototype
- 构造的过程
func
作为构造函数被执行,上下文是新对象
函数
函数的构造函数
对象的构造函数:Function
,所有的函数由Function
构造创建
函数的原型对象:prototype
存在于构造函数上,拥有一个construtor
属性指向创建它的构造函数
对象的原型:
Object.prototype
- 所有对象的
__proto__
最终指向它 - 它的
__proto__
为null
- 定义了
valueOf
、toString
等公用方法
- 所有对象的
函数的原型:
Function.prototype
- 所有的构造函数的
__proto__
指向它 - 作为对象它的
__proto__
最终也会指向Object.prototype
- 所有的构造函数的
对象
对象的构造函数
对象的构造函数:Object
,普通对象由Object
构造函数创建
对象的原型链属性:__proto__
存在于对象上(字面量或者new
出来的对象,会为新对象添加__proto__
属性) 指向创建该对象的构造函数的原型:
- 构造函数则是构造函数的原型:
Foo.prototype
- 字面量对象则是:
Object.prototype
javascript
中防止被篡改的对象
当我们希望定义的对象不能被修改、删除和新增时,我们可以把对象设置为防篡改的。
防篡改的等级:
根据对对象的要求,我们可以把防篡改对象分为三个级别
1. 不可扩展对象
正常的对象都是可以新增属性和方法的:
const obj = {
title:'hello world'
}
obj.say = function(){
alert(this.title)
}
通过下面的api
可以实现对对象的可扩展控制
Object.preventExtensions(Object)
:将对象设置为不可扩展Object.isExtensible(Object)
:判断对象是否可扩展
Object.preventExtensions(obj)
obj.content = 'yes'
// undefined
console.log(obj.content)
// false
Object.isExtensible(obj)
值得注意的事:
非严格模式下,对设置的对象新增属性和方法静默失败,严格模式下报错
该设置针对新增属性和方法,修改和删除已有属性不影响
2. 密封对象
在不可扩展的基础上增加了不可删除设置,密封对象的[[Configurable]]
描述属性会被设置为false
,即不能删除,但是仍然可以修改。
通过下面的api
可以实现对对象的密封设置
Object.seal(Object)
:将对象设置为密封Object.isSealed(Object)
:判断对象是否已密封
Object.seal(obj)
delete obj.title
// hello world
console.log(obj.title)
// true
Object.isSealed(obj)
值得注意的事:
- 非严格模式下,对设置的对象新增和删除属性静默失败,严格模式下报错
3. 冻结对象
在上面两个级别的基础上,增加了不可修改配置,防篡改级别达到最高。被设置的对象不能新增属性、修改属性、删除属性,对象的[[Writable]]
描述属性也会被设置为false
,即不可修改
通过下面的api
可以实现对对象的冻结设置:
Object.freeze(Object)
:将对象设置为冻结Object.isFrozen(Object)
:判断对象是否已冻结
Object.freeze(obj)
// 无效
obj.content = 'yes'
// 无效
obj.title = 'hello city'
// 无效
delete obj.title
// true
Object.isFrozen(obj)
值得注意的事:
- 非严格模式下,对冻结的对象进行操作会静默失败,严格模式下报错
原型链
在查找新对象的属性时,如果没有,就会根据__proto__
层层向上查询,直到顶层对象Object.prototype
如何理解串联
对象(函数也是对象)都是由构造函数创建的
- 函数由
Function
构造 - 对象由
Object
构造或其他构造函数Foo
构造
- 函数由
函数和对象的交叉
函数拥有特殊属性对象:
prototype
,拥有一个construtor
属性指向创建它的构造函数Function
对象拥有特殊指针:
__proto__
,指向创建它的构造函数的原型Function.prototype
:(函数也是对象)Object.prototype
或Foo.prototype
顶级构造函数
Object
、Function
,它们由原生代码构造(prototype.constructor
指向原生代码)。对象的顶级构造函数
Object.prototype.__proto__
指向null