一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
-
我们可以通过
__proro__(非标准)或Object.getPrototypeOf获取某个实例的原型 -
我们可以利用call方法借用父构造函数绑定父类的属性(不可以继承父类的方法)
-
将子构造函数的prototype属性赋值为父构造函数的prototype属性
- 问题:在修改子构造函数的prototype属性时,会一并把父构造函数的prototype属性给污染了
-
通过将子构造函数的prototype属性赋值为父类的实例对象时,虽然可以继承父类的方法,但是有个缺点:
- 如果父构造函数有形参,在创建父类实例时,就不太符合语义
-
如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数
实现继承的最佳方式,可以借助Object.create方法
Object.create 的作用:创建一个对象,并返回,这个对象的原型指向第一个实参
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 坚持一种代码风格
// 每个独立的逻辑块,适当的换行,可以增加代码的可读性
function Father(uname, age) {
this.uname = uname
this.age = age
}
Father.prototype.hehe = function () {
console.log('heheda')
}
function Son() {
// Father.call(this)
}
// Son.prototype = Father.prototype
// Son.prototype = new Father()
// Object.create 的作用:创建一个对象,并返回,这个对象的原型指向第一个实参
var obj = Object.create(Father.prototype)
Son.prototype = obj
Son.prototype.constructor = Son
Son.prototype.haha = function () {
console.log('haha');
}
</script>
</body>
</html>
函数在定义时的参数叫形参,调用时的参数叫实参
class实际就是ES6新出来的语法(语法糖),本质还是function,之前有的特点都有
可以通过extends关键字来实现继承,形如:class Son extends Father { }
数组方法:
- forEach方法的第一个参数是一个函数,函数的第一个参数是元素,第二个参数才是索引号,与变量名没关系,顺序是固定的
- 不能写continue、break,return也不能终止循环,想要终止循环,可以用some方法
- filter方法,是用来过滤数组元素
- 接收一个函数作为参数,这个函数的第一个形参是元素,第二个形参是索引号
- 内部会有循环机制,每次循环都会调用函数,如果函数返回true,则保留当前循环元素,如果返回false,则剔除当前循环元素
- 会返回一个新数组,不会影响原来的数组,我们也称之为非变异方法
- some方法,是用来看数组中是否存在符合条件的元素(运行机制:内部也有循环机制,每次循环也会调用函数,只要函数返回true,则终止循环,some函数也返回true,若果循环结束,还没有一个返回true,则some函数返回false)
- 返回值是布尔值,如果有,则返回true,否则返回false
- 一旦找到符合条件的,则立即终止循环
- 当循环逻辑比较复杂或耗时时,可以提高一丢丢性能
- map方法,用来做映射,返回值是数组,内部会有循环机制.........,实参函数的返回值会组成一个新的数组返回
- every方法,和some类似,但必须每一个都符合条件,才返回true,反之,只要有一个不符合条件,就返回false
非变异方法和变异方法的区别就是看调用完这个方法后,会不会影响原数组,有则是变异方法,无则是非变异方法
写代码时,要逐步测试,不要写了一百行,再来测试,如果报错了,这个时候你很可能懵逼,不知道到底是哪一行代码引起的
forEach和some的区别:
- forEach不可以通过return终止循环,也不可以使用continue、break
- some可以通过return true(why? 乌龟的尾巴,死龟腚)终止循环,在只需要找到某个元素时,效率更高
.trim()方法就是去除字符串的前后空格,中间的不会去掉
Object.keys(obj)返回obj对象自身(拿不到原型链上的属性)的所有键名组成的数组
Object.defineProperty方法可以给某个对象添加或修改属性,基本语法:
Object.defineProperty(obj, propertyName, discreptor):
-
obj:操作的对象
-
propertyName:属性名,字符串型
-
discreptor:属性描述符,是对象:
- value:属性值,默认值是undefined
- writable:是否可写,默认值是false,不可写(不能被重新赋值)
- enumerable:是否可枚举(是否可以被for...in或Object.keys()方法获取到键名),默认值是false
- configurable:是否可配置(是否可以被delete删除或者重新配置属性(重新配置时,会直接报错))
- get:是一个函数,当访问该属性时,该函数就会执行,函数的返回值就是获取的属性值,默认值是undefined
- set:是一个函数,当给该属性赋值时,该函数就会执行,函数的第一个形参就是想要赋的值
补充说明,这里的默认值(writable、enumerable、configurable),说的是通过Object.defineProperty方法添加的属性,如果是通过对象字面量创建的,默认值都是true
存取描述符范例:
var obj = { name: '张三', age: 18 } function setSex(sex) { Object.defineProperty(obj, 'sex', { // 取 get: function () { console.log('想要获取sex?哈哈,可以在这里搞点事情') return sex === 'male' ? '男' : '女' }, // 存 set: function (val) { console.log('想要给sex赋值?呵呵,又被拦截到了,也可以在这里搞点事情') sex = val } }) } setSex('male')
属性描述符分为三种:
- 公共描述符(enumerable、configurable)
- 数据描述符(value、writable)
- 存取描述符(get、set)
- 注意:数据描述符和存取描述符不能都用,公共描述可以都用
可以通过这个方法获取到某对象的某个属性的描述符:Object.getOwnPropertyDescriptor(obj, propertyName)