javascript高级开发学习笔记五

来源:互联网 发布:淘宝卖家给买家差评 编辑:程序博客网 时间:2024/06/05 20:06

1.ECMA-262把对象定义为:“无序属性的集合,其属性可以包含其基本值、对象或者函数。”

   ECMA-262在定义只有内部才用的特性时,描述了属性和各种特征,这些特性是为了实现javascript引擎用的,因此在javascript中不能直接访问他们。特性为内部值,该规范把它们放在两对方括号中。

   ECMAScript中的两种属性:数据属性和访问器属性。

   1.1数据属性:数据属性包含一个数据值的位置。这个位置可以读取和写入值。

[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。默认true。

        [[Enumerable]]:表示能否通过for-in循环返回参数。默认true。

        [[Writable]]:表示能否修改属性的值。默认true。

        [[Value]]:包含这个属性的数据值。读取数据值的时,从这个位置读取。写入数据值时,新值保存到这里。默认undefined。


要修改属性的默认参数,必须使用ECMAScript5的Object.defineProperty()方法。该方法三个参数:属性所在的对象、属性的名字、一个描述符对象(必须为以上四个)。

在调用Object.defineProperty()方法时,不指定configurable、enumerable、writable,默认值都是false。

   1.2访问器属性:访问器属性不包含数据值;它们包含getter(读取)和setter(写入)函数。

[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。默认true。

         [[Enumerable]]:表示能否通过for-in循环返回参数。默认true。

[[Get]]:读取属性时调用的函数。默认undefined

[[Set]]:写入属性的调用的函数。默认undefined

访问器属性不能直接定义,必须使用Object.defineProperty()来定义。在这个方法之前,要创建访问器属性,一般都使用两个非标准的方法:_defineGetter_()和_defineSetter_()。


定义多个属性使用Object.definePropertys()方法。

获取给定属性的描述符使用Object.getOwnPropertyDescriptor()方法,该方法有两个参数:属性所在的对象和要读取描述符的属性名称。返回值为对象,如果是访问器属性,这个对象有configurable、enumerable、get、set;如果是数据属性,这个对象有configurable、enumerable、writable、value。


2.创建对象

     2.1 工厂模式

     2.2 构造函数模式

     2.3 原型模式

                 创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。                      prototype就是通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象的好处是可以让所有的对象实例共享它所包含的所有属性和方法。

                 理解原型对象:(1)创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。默认情况下,所有原型对象都会自动获得一个constructor属性,这个属性包含一个指向prototype所在函数的指针。(2)创建自定义构造函数之后,其原型对象默认只会取得constructor属性;至于其它方法,则都是从Object继承而来。当调用构造函数创建一个新实例后,该实例的内部包含一个指针,指向构造函数的原型对象。ECMA-262中,把这个指针叫[[Prototype]](无法访问到),该链接存在于实例与构造函数原型对象之间,不是存在于实例和构造函数之间。(3)我们用原型对象的isPrototypeOf()方法,判断实例是否有一个指向原型的指针。(4)ECMAScript中新方法Object.getPrototypeOf(),该方法返回实例原型[[Prototype]],所以通过Object.getPrototypeOf()方便得到对象的原型,并实现继承。(5)虽然可以通过对象实例访问保存在原型中的值,但不能通过对象实例重写原型对象中的值。如果我们在实例中添加了与原型对象中相同名称的属性,实例对象中的属性会屏蔽原型中的属性。delete可以完全删除实例属性,从而解除对原型属性的屏蔽。(6)Object继承而来的方法hasOwnProperty()可以检测一个属性是存在于实例中,还是存在于原型中。给定属性存在于对象实例中时,才会返回true。(7)in 操作符会在通过对象能够访问给定属性时true。for-in返回的是所有能够通过对象访问的、可枚举的属性。


     Object.keys():接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组。

     Object.getOwnPropertyNames():得到所有实例属性,无论是否可枚举。

            问题:(1)省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的值。(2)原型中的所有属性都是共享的,当某一属性为引用类型时。一个实例对数据进行操作后,会影响另一个实例。

       2.4 组合使用构造函数模式和原型模式(构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性)

       2.5 动态原型模式:把所有的信息都封闭到了构造函数中,而通过构造函数初始化原型。也就是说,可以通过检查某个应该存在的方法是否有效,来决定是否初始化原型。

       2.6 寄生构造函数模式:创建一个函数,该函数的作用仅仅是封闭对象的代码,然后再返回新创建的对象。

       2.7 稳妥构造函数模式:稳妥对象指没有公共属性,而且其方法也不引用this的对象。稳妥对象最适合在一些安全环境(这种环境中禁止使用this和new)中,或者在防止数据被其它应用程序改动时使用。

3.继承(ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的)

       3.1 原型链:思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。

                             在通过原型链实现继承时,不能使用对象字面量创建原型方法,这样做会重写原型链。

      3.2 借用构造函数:思想是在子类型构造函数内部调用超类型构造函数。函数只不过是特定环境中执行代码的对象,因此通过使用apply()和call()方法也可以在新创建的对象上执行构造函数。(1)可传递参数;

      3.3 组合继承:将原型链和借用构造函数组合在一起。使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承。

      3.4 原型式继承:借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。

                      Object.create()方法规范化了原型式继承。这个方法接收两个参数:一个用作新对象原型的对象和(可选)一个为新对象定义额外的属性。

      3.5 寄生式继承:创建一个仅用于封闭继承过程的函数,该函数在内部以某种方式来增强对象,再返回对象。

      3.6 寄生组合式继承:通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。不必为了指定子类型的原型而调用超类型的构造函数。

0 0
原创粉丝点击