javascript作为一个面向对象的语言,理解 对象、原型、闭包、模块模式等技术点对于成为一名合格的javascript程序员相当重要,多年没写过blog,今天就先拋个玉,在下基本也不做前端,但颇感兴趣,愿意和大家一起学习。此篇只是对自己认为的比较重要的知识点进行了说明,连贯性不是特别好,大家共同进步。
注意:文中中文并非英文翻译,只是个人理解。
理解面向对象
对象(object)
An object is a collection of properties and has a single prototype object. The prototype may be the null value
无序属性的集合,其属性可以包含基本值、对象或者函数。
Prototype
object that provides shared properties for other objects。
为其他对象提供属性的对象。
属性分为数据属性和访问器属性。
数据属性
Attribute Name |
Value Domain |
Description |
[[Value]] |
Any ECMAScript language type |
The value retrieved by a get access of the property. 可以通过属性获取值 |
[[Writable]] |
Boolean |
If false, attempts by ECMAScript code to change the property‘s [[Value]] attribute using [[Set]] will not succeed. 默认true 如果是false,不能修改属性值 |
[[Enumerable]] |
Boolean |
If true, the property will be enumerated by a for-in enumeration (see 13.7.5). Otherwise, the property is said to be non-enumerable. 默认true 是否可以通过for in 返回属性值 |
[[Configurable]] |
Boolean |
If false, attempts to delete the property, change the property to be an accessor property, or change its attributes (other than [[Value]], or changing [[Writable]] to false) will fail. 默认是ture。 如果是false 通过delete删除属性,重新定义属性,把属性修改成访问器属性就会失败。 |
Object.defineProperty ( O, P, Attributes )
The defineProperty function is used to add an own property and/or update the attributes of an existing own property of an object. When the defineProperty function is called, the following steps are taken:
If Type(O) is not Object, throw a TypeError exception.
Let key be ? ToPropertyKey(P).
Let desc be ? ToPropertyDescriptor(Attributes).
Perform ? DefinePropertyOrThrow(O, key, desc).
Return O.
var Bird ={ name:"poly" }; console.log(Bird.name) Object.defineProperty(Bird,"name",{ writable:false, value:"poly" }) console.log("before:"+Bird.name); Bird.name="lily" console.log("after:"+Bird.name);
访问器属性
Attribute Name |
Value Domain |
Description |
[[Get]] |
Object | Undefined |
If the value is an Object it must be a function object. 读取属性时候调用该函数 |
[[Set]] |
Object | Undefined |
If the value is an Object it must be a function object. 写入属性时调用此函数 |
[[Enumerable]] |
Boolean |
If true, the property is to be enumerated by a for-in enumeration. Otherwise, the property is said to be non-enumerable. 可以通过for-in 循环返回属性。 默认值是true |
[[Configurable]] |
Boolean |
If false, attempts to delete the property, change the property to be a data property, or change its attributes will fail. 可以通过delete 删除并修改属性。 |
var singal={ _ip:"192.168.2.7", port:1111 }; Object.defineProperty(singal,"ip",{ get:function() { return this._ip; }, set:function(value) { if(value!=1111) { this._ip = "192.168.1.7" } } }) singal.ip=1234 console.log("ip:"+singal.ip);
理解原型对象
function Signal(){}; Signal.prototype.ip="192.168.0.7"; Signal.prototype.port =1111; Signal.prototype.connect=function() { console.log("connecting ..."); } var singal_01 = new Signal(); var singal_02 = new Signal(); singal_01.connect(); singal_02.connect(); 所有实例共享这些属性和方法。 console.log(singal_01.connect == singal_02.connect);//true
创建新函数,自动为该函数创建一个prototype属性(指针),这个属性指向函数的原型对象默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性的指针。
in
只要通过对象能够访问到属性就返回true
hasOwnProperty
只在属性存在于实例中返回True
使用delete 可以删除实例属性。
原型对象缺点:
1 省略了为构造函数传递初始化参数,所有实例默认值都相同
2. 对引用数据类型的属性造成修改后,所有实例都修改。
注意: 重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系。
闭包
闭包是指有权访问另一个函数作用域中的变量的函数。
funcation add(x) { return funcation(y) { console.log(x+y) } }
当某个函数第一次调用时,会创建一个执行环境及相应的作用域链,并把作用域链赋值个一个特定的属性[scope]
对于闭包来说,内部函数会把外部函数的活动对象添加到自己的作用域中。
模块模型自认为特别重要,后期会专门写一篇和大家共同讨论。