JavaScript-winter-2

原型回顾

上次讲原型和原型链,对比Java中的继承和重写其实不难理解,原型是function对象的一个属性,它定义了构造函数构造出的对象的公共祖先,由构造函数产生的对象,可以继承对应原型的属性和方法,原型也是对象。
原型链就是把原型串起来,在原型上面再加一个原型,再加一个原型,使用__proto__连接各个原型。
还学到了原型链的增删改查,一般情况下不能通过后代改父代,但要注意可以修改的情况。见前文
好友call/apply的作用和不同点,作用是改变this指向,在起夜开发中可用于组装部件,apply的区别在于把参数写成一个数组传进去,而不是像call那样一个一个传进去

继承模式

extend走过许多发展史,

  1. 原型链只是继承的一种方法,虽然简单,但是它也会继承许多没用的属性
  2. 于是有了call/apply那种借用构造函数的方式,虽然它不太像继承,缺点是它不能继承借用构造函数的原型,且每次构造函数都要走一个函数,从视觉上减少了代码量,但是运行成本并没有减少。
  3. 然后到了现在使用很多的共享原型的模式,即多个构造函数使用一个原型,直接赋值即可,比如Target.prototype = Origin.prototype;
  4. 第三种我们会发现Target.prototypeOrigin.prototype完全指向了一个空间,修改其中一个另一个势必也会跟着修改,这或许不是我们想要的,圣杯模式恰好解决了这种问题,此时改动Son的prototype并不会改变Father的,这就是圣杯模式
    JavaScript-winter-2
    在雅虎YUI库中有关继承的封装好的函数,是像下面这样写的,有什么好处呢?
    JavaScript-winter-2
    好处是使用了闭包和立即执行函数,私有化变量,不污染执行环境,对比前一种方法,F根本只起了一个中间层的作用

命名空间

namespace就是对象,大型项目有多人开发,可能存在定义了同名变量,那么就把变量放到命名空间统一管理,防止污染全局,适用于模块化开发,同时此处的模块化开发也是闭包的用处之一
现在流行的解决方式是webpack

对象枚举

附加

对象属性访问

属性访问器

  • 方括号运算符:方括号运算符内可以是表达式,表达式必须返回字符串或一个可以转换为字符串的值(因为有些代码就是使用字符串来作为对象的键)
  • 点运算符:右侧必须是一个标识符,只能表示键是一个合法的标识符且不是一个保留字的情况

若在属性中没有找到相关的键,就会返回undefined
其中属性分为自有属性(直接在对象中定义的属性) 和继承属性(在当前对象的原型对象中定义的属性)

JavaScript-winter-2

以前笔记提到过,在前后端交换数据时,为了避免直接报错,可以使用或运算符或者与运算符

属性检测与遍历

属性检测
JS有三种方法检测某个属性是否在特定的对象中

  • in:检测属性是否为特定对象的自有属性继承属性 例如'name' in person输出true
  • hasOwnProperty():确定JS对象是否具有指定的自有属性。例如person.hasOwnProperty("name")输出true
  • propertyIsEnumerable():该propertyIsEnumerable()方法返回一个布尔值,该布尔值指示指定的属性是否可枚举并且是对象自己的属性。例如person.propertyIsEnumerable("name")输出true

什么是属性的可枚举性?
属性的特性之一,用来描述属性是否可以用一般的遍历操作获取到值,可枚举属性是其内部可枚举标志设置为true的那些属性,这是通过简单赋值或通过属性初始化器创建的属性的默认值(通过Object.defineProperty定义的属性,此类默认可枚举为false)。

属性遍历
JS提供三种方法遍历对象中的属性

  • for...in:遍历由字符串键控的对象的所有可枚举属性(忽略由Symbol键控的那些),包括继承的可
    JavaScript-winter-2
  • Object.keys(person):返回一个数组,数组中的元素是对象中的可枚举的自有属性的名称,输出(3) ["name", "isMale", "age"]
  • Object.getOwnPropertyNames(person):返回一数组,数组中的元素是对象中所有自有属性的名称

存取器属性

只能get方法,即只能读,只有set方法,即只能写,读取只写属性返回undefined
由这两个方法定义的属性称为存取器属性,而有其他简单的值定义的属性称为数据属性
存取器详情见此文

属性的特性

下面的文字源于shangCW的文章

除了在前文提到的可枚举性之外,对象的属性还有其它的特性,比如说可枚举性、可配置性等等
如果我们把数据属性的值看作是一个特性,那么数据属性总有具有四个特性,分别是

  • 值(value):数据属性的值,默认为 undefined
  • 可写性(writable):是否可以修改属性的值,默认为 true
  • 可枚举性(enumerable):是否可以通过 for/in 循环获取到值,默认为 true
  • 可配置性(configurable):是否可以删除和修改属性,默认为 true

如果我们把存取器属性的 getter 和 setter 方法也看作是特性,那么存取器属性同样具有四个特性,分别是

  • 读取(getter):在读取属性时调用的函数,默认为 undefined
  • 设置(setter):在设置属性时调用的函数,默认为 undefined
  • 可枚举性(enumerable):是否可以通过 for/in 循环获取到值,默认为 true
  • 可配置性(configurable):是否可以删除和修改属性,默认为 true
    至此,我们对属性又有一个不同的理解:对象的属性是由一个名字(键)和四个特性组成的
  1. 可使用Object.getOwnPropertyDescriptor(square, "x")来获取获取自有属性的描述符,输出如下
    JavaScript-winter-2
  2. 可使用使用 Object.defineProperty() 方法设置属性的特性
    JavaScript-winter-2
    注意最后的输出结果,因为get area()只读,而set area()只写,x又被我设置了不可枚举,所以只能输出area
JavaScript-winter-2JavaScript-winter-2 YAMA小麦 发布了58 篇原创文章 · 获赞 26 · 访问量 8753 私信 关注
上一篇:Python进阶之路 多重赋值技巧


下一篇:2021年4月份,京东算法岗面试题4道