JavaScript高等程序设计-择要笔记-2

申明:

此择要笔记系列是我近来看《JavaScript高等程序设计(第3版)》顺手所记。
内里分条列举了一些我以为主要的、须要记下的、对我有协助的点,是根据我看的递次来的。
择要笔记本身没有系统性,没有全面性可言,写在这里供有肯定基本的前端开发者参考交换。
内里的知识点、例子大部分来源于本书,或许延长出来的,都经由我的测试是对的,然则没要领保证100%准确,如果有人看到毛病的处所,愿望指出来,感谢。

1. Math 对象

Math.E // 2.718281828459045 自然对数的底数,即常量 e 的值
Math.PI // 派的值 3.141592653589793
Math.min() // 一组数中的最小值
Math.max() // 一组数中的最大值
// 获得数组中最大值的要领
var arr = [10, 15, 8, 23]
var max = Math.max.apply(Math, arr)
console.log(max) // 23
Math.ceil() // 向上取整
Math.floor() // 向下取整
Math.round() // 四舍五入取整
Math.random() // 返回大于即是0小于1的随机数
Math.abs(num) // 返回 num 的绝对值
Math.log(num) // 返回 num 的自然对数
Math.pow(num, power) // 返回 num 的power次幂
Math.sqrt(num) // 返回 num 的平方根
Math.cos(x) // 返回 x 的余弦值
Math.sin(x) // 返回 x 的正弦值
Math.tan(x) // 返回 x 的正切值
Math.acos(x) // 返回 x 的反余弦值
Math.asin(x) // 返回 x 的横竖弦值
Math.atan(x) // 返回 x 的横竖切值
Math.atan2(y, x) // 返回 y / x 的横竖切值

2. 深度拷贝对象的简朴高效要领

var rel = JSON.parse(JSON.stringify(obj))

3. Object.assign() 要领可以把恣意多个的源对象本身的可罗列属性拷贝给目的对象,然后返回目的对象Object.assign(target, …sources),如:

var obj = {a: 1}
var copy = {b: 3}
var rel = Object.assign(b, obj)
console.log(rel) // {a: 1, b: 3}
copy === rel // true

如果须要深度拷贝的话,依旧须要运用别的而不是本要领。由于 Object.assign() 拷贝的是在 source 里是对象的属性的援用而不是对象本身。如:

var a = {b: 3, c: {e: 5}}
var rel = Object.assign({}, a)
console.log(rel.c.e) // 5
a.c.e = 8
console.log(rel.c.e) // 8
// 兼并 objects
var o1 = {a: 2}
var o2 = {b: 5}
var o3 = {c: 8}
var rel = Object.assign(o1, o2, o3)
console.log(rel) // {a: 2, b: 5, c: 8}
console.log(o1) // {a: 2, b: 5, c: 8}
rel === o1 // true
// 继续属性和不可罗列属性是不能拷贝的
// 原始范例会被包装为 object

4. 对象的属性

ECMAScript 中有两种属性:数据属性和接见器属性

a. 数据属性:数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个形貌其行动的特征。
[[Configurable]]: 可否经由过程 delete 删除属性从而从新定义属性,可否修正属性的特征,或许可否把属性修正为接见器属性。默许 true 。
[[Enumerable]]: 可否经由过程 for-in 轮回返回属性。默许 true 。
[[Writable]]: 可否修正属性的值。默许 true 。
[[Value]]: 包含这个属性的数据值。读取属性的时刻从这个位置读;写入属性值的时刻,把新值保留在这个位置。默许值 undefined 。

要修正属性默许的特征,须要经由过程 es5 的 Object.defineProperty() 要领。这个要领接收三个参数,属性地点的对象,属性的名字和一个形貌符对象。
个中,形貌符 (descriptor) 对象的属性必需是:configurable, enumerable, writable, value. 设置个中一个或多个值,可以修正对应的特征值。如:

var person = {}
Object.defineProperty(person, 'name', {
  writable: false,
  value: 'abc'
})
person.name // 'abc'
person.name = 'wfc' // 严厉形式下会报错
person.name // 'abc'

在挪用 Object.defineProperty() 要领时,如果不指定,configurable, writable, enumerable 的默许值都是 false。

可以屡次挪用 Object.defineProperty() 来修正同一个属性,然则在把 configurable 特征设置为 false 以后,
就只能把 writable 从 true 改成 false,别的设置都邑报错。

b. 接见器属性

接见器属性不包含数据值,它们会包含一对 getter setter 函数(都不是必需的)。在读取接见器属性时,会挪用 getter 函数,这个函数担任返回有用的值;
在写入接见器属性时,会挪用 setter 函数并传入新值,这个函担任决议怎样处置惩罚数据。接见器属性有以下4个特征:

[[Configurable]]: 示意可否经由过程 delete 删除属性从而从新定义属性,可否修正属性的特征,或许可否把属性修正为数据属性。
关于直接在对象上定义的属性,默许值 true 。
[[Enumerable]]: 示意可否经由过程 for-in 轮回返回属性。关于直接在对象上定义的属性,默许值 true 。
[[Get]]: 在读取属性时挪用的函数。默许值 undefined 。
[[Set]]: 在写入属性时挪用的函数。默许值 undefined 。

接见器属性不能直接定义,必需运用 Object.defineProperty() 来定义。如:

var book = {
  _year: 2016,
  edition: 1
}
Object.defineProperty(book, 'year', {
  get: function () {
    return this._year
  },
  set: function (newValue) {
    this.edition += 1
    this._year = newValue
  }
})
book.edition // 1
book.year = 2017
book.edition // 2

不必要同时指定 getter setter , 只指定 getter 意味着属性不能写,只指定 setter 意味着属性不能读

// 支撑 Object.defineProperty() 的浏览器 IE 9+,Firefox 4+, Safari 5+, Opera 12+, Chrome

5. Object.defineProperties() 可以经由过程形貌符一次定义多个属性。这个要领接收两个参数,第一个参数是要增加和修正其属性的对象,

第二个参数是形貌符。如:

var book = {}
Object.defineProperties(book, {
  _year: {
    value: 2016,
    writable: true
  },
  edition: {
    value: 1,
    writable: true
  },
  year: {
    get: function () {
      return this._year
    },
    set: function (value) {
      this._year = value
      this.edition += 1
    }
  }
})
// 支撑 Object.defineProperties() 的浏览器 IE 9+,Firefox 4+, Safari 5+, Opera 12+, Chrome

6. Object.getOwnPropertyDescriptor() 可以获得指定属性的形貌符。接收两个参数,属性地点对象,属性称号。

只能获得实例属性的形貌符,要获得原型对象的形貌符,要在原型对象上挪用这个要领。
如上例中的 book :

Object.getOwnPropertyDescriptor(book, '_year') // {configurable: false, enumerable: false, writable: true, value: 2016}
var rel = Object.getOwnPropertyDescriptor(book, 'year')
console.log(rel)
// {
//   configurable: false,
//   enumerable: false,
//   get: function () {
  //   return this._year
  // },
  // set: function (value) {
  //   this._year = value
  //   this.edition += 1
  // }
// }
typeof rel.get // 'function'
// 支撑 Object.getOwnPropertyDescriptor() 的浏览器 IE 9+,Firefox 4+, Safari 5+, Opera 12+, Chrome

7. 关于 OO

function Person (name, age) {
  this.name = name
  this.age = age
  this.sayName = function () {
    console.log(this.name)
  }
}
var ming = new Person('ming', 13)

Person.prototype.constructor === Person // true
ming.constructor === Person // true
Person.constructor === Function // true
Function.constructor === Function // true
Function instanceof Function // true
Function instanceof Object // true

Person.prototype.sayHello = function () {
  console.log('hello')
}
ming.sayHello() // 'hello'
ming.__proto__.constructor === Person // true
ming.__proto__ === Person.prototype // true

8. 组织函数

组织函数与别的函数唯一的区分在于挪用体式格局的差别,不存在定义组织函数的特别语法。如果不经由过程 new 操作符来挪用,那它跟一般函数没有区分。如上面的例子:

var li = new Person('li', 15)
li.sayName() // 'li'

Person('yang', 18)
window.sayName() // 'yang'

var o = {}
Person.call(o, 'wang', 20)
o.sayName() // 'wang'

9. 原型形式

我们建立的每一个函数都有一个 prototype(原型) 属性,这个属性是一个指针,指向一个对象,这个对象的用处是包含一切实例同享的属性和要领。如:

function Person (name, age) {
  this.name = name
  this.age = age
  this.sayName = function () {
    console.log(this.name)
  }
}
Person.prototype.sayHello = function () { console.log('hello') }
var ming = new Person('ming', 12)
var li = new Person('li', 15)
ming.sayHello === li.sayHello // true
ming.sayHello === Person.prototype.sayHello // true

可以经由过程 isPrototypeOf() 要领来肯定对象直接是不是存在 原型-实例 关联,如:

Person.prototype.isPrototypeOf(ming) // true

es5 新增要领 Object.getPrototypeOf() 这个要领返回实例的 proto 即实例的组织函数的原型的值,如:

Object.getPrototypeOf(ming) === Person.prototype
// 支撑 Object.getPrototypeOf() 的浏览器 IE 9+,Firefox 3.5+, Safari 5+, Opera 12+, Chrome

10. hasOwnProperty() 要领可以检测一个属性是存在于实例中,照样原型中。这个要领只在属性存在于实例中时才返回 true 。in 操作符零丁运用,只需可以经由过程该对象接见给定属性就返回 true, 如上例:

ming.hasOwnProperty('sayHello') // false
'sayHello' in ming // true
ming.hasOwnProperty('sayName') // true
'sayName' in ming // true

ming.sayHello = function () {
  console.log('hello in self')
}
ming.hasOwnProperty('sayHello') // true
'sayHello' in ming // true
delete ming.sayHello
ming.hasOwnProperty('sayHello') // false
'sayHello' in ming // true

ming.hasOwnProperty('sayHello1') // false
'sayHello1' in ming // false

纵然将实例属性设置为 undefined / null , hasOwnProperty() in 这两个要领依然返回 true

function hasPrototypeProperty (object, name) {
  return !object.hasOwnProperty(name) && name in object
}

for-in 轮回返回的是一切可以经由过程对象接见的、可罗列的(enumerable: true)属性,既包含实例中的属性又包含原型中的属性。

11. es5 的 Object.keys() 要领,接收一个对象作为参数,返回实例上一切可罗列属性的字符串构成的数组。如:

var Person = function () {}
Person.prototype.sayHello = function () {
  console.log('hello')
}
var ming = new Person()
ming.name = ming
Object.keys(ming) // ["name"]

Object.getOwnPropertyNames() 要领可以获得一切实例属性,包含不可罗列的。
// 支撑 Object.keys() 和 Object.getOwnPropertyNames() 的浏览器 IE 9+,Firefox 4+, Safari 5+, Opera 12+, Chrome
    原文作者:wfc_666
    原文地址: https://segmentfault.com/a/1190000007751608
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞