- 面向过程就是一步步实现解决问题的步骤
- 打开冰箱,放大象,关门
- 不易维护,联系紧密
- 面向对象是把事务分解为一个个的对象,然后对象间分工合作
- 大象对象:进入
- 冰箱对象:打开,关闭
- 容易维护,复用,扩展,耦合度低
- JS对象由属性方法构成
- 对象是类的实例化
ES6类的继承
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() { // 必须这么写
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor(x, y) {
super(x, y); //作用是调用father构造器,如果不写这句话,son1.sum()会报错,因为其实x,y是写到Father里的,sum调用Father的属性
}
}
var son1 = new Son(100, 200);
son1.sum();// => 300
- 继承中如果子类实例化输出方法,先看子类有没有,没有就看父类有没有,如果有就执行这个方法
- 子类构造函数必须把super放在this前面
- ES6中类没有变量提升,必须定义类才能实例化对象
- 类的属性和方法一定要加this使用
- constructor里面的this指向实例对象,方法里面的this指向这个方法的调用者
- ES6前,对象不是基于类创建的,而是用一种称为构建函数的特殊函数来定义对象和他们的特征
// 利用对象字面量创建对象
var obj = {}
// 利用构造函数创建对象
function Person(age, name) {
this.name = name;
this.age = age;
this.walk = function(){
console.log("walk");
}
}
var xiaoming = new Person('xiaoming', 18);
console.log(xiaoming); // => Person {name: 18, age: "xiaoming", walk: ƒ}
xiaoming.walk(); // => walk
new的过程的本质
-
new构造函数的过程中做的4件事
- 在内存中创造新的空对象
- 让this指向这个新对象
- 执行构造函数里面的代码,给这个新对象添加属性和方法
- 返回这个新对象
静态成员对象
-
静态成员:在构造函数本身添加的成员, 如
Person.sex = '男'- 静态成员属于类不属于实例,实例中没有这个属性
-
实例成员:构造函数通过this添加的成员,只能通过实例化的对象来访问
-
构造函数浪费内存,不同对象同样的方法放在不同地址空间
- 构造函数通过原型分配的函数是所有对象所共享的
- 每个构造函数都有一个prototype对象
- 把不变的方法直接定义在prototype对象上,所有的对象实例就可以共享这些方法
- 原型就是prototype称为原型对象
- 原型的作用是共享方法
Person.prototype.walk = function(){}- 对象身上系统自动添加
__proto__(对象原型)指向我们构造函数的原型对象xiaoming.__proto__ === Person.prototype // => true
-
原型对象里面有constructor属性,很多情况下,我们需要手动利用constructor这个属性指回原来的构造函数
-
function Person(age, name) { this.name = name; this.age = age; this.walk = function(){ console.log("walk"); } } console.log(Person.prototype.constructor); /* ƒ Person(age, name) { this.name = name; this.age = age; this.walk = function(){ console.log("walk"); } } */ -
如果修改了原型对象,给原型对象赋值一个对象,要让constructor指回原来的构造函数
constructor: Person -

原型链
-
原型链:先在对象里找有没有成员,然后顺着原型链找原型对象里面有没有(
原型对象.__proto__就可以找到原型对象指向的原型对象)
- 原型对象的函数里面的this指向的是实例对象
-
扩展内置对象
-
Array.prototype.sum = function () { var sum = 0; for(let i = 0; i < this.length; i++) { sum += this[i]; } console.log(sum); } var arr = [1, 2, 3]; arr.sum(); // => 6
-
-
call
-
可以改变函数的this指向
-
var obj = {} function f(x, y) { console.log(this); console.log(x + y); } fn.call(obj, 1, 2); // obj 3
-
ES5继承
-
继承属性
-
ES5通过构造函数+原型对象实现继承,对于属性,通过call把父类的this指向子类的this就可以实现基础父类属性,对于方法,
-
function Father(name, age){ this.name = name; this.age = age; } function Son(name, age, score){ // new Son时 this指向son,再把Father this指向改成son Father.call(this, name, age); this.score = score; } var son = new Son('xiaoming', 16, 88); console.log(son); //=> Son {name: "xiaoming", age: 16, score: 88}
-
-
继承方法
-
function Father(name, age) { this.name = name; this.age = age; } Father.prototype.money = function () { console.log(100); } function Son(name, age, score) { Father.call(this, name, age); this.score = score; } Son.prototype = new Father(); Son.prototype.constructor = Son; Son.prototype.exam = function () { console.log("要考试"); } var son = new Son('xiaohua', 18, 100); -

-
ES6类的本质
- 类的本质还是一个函数,可以认为类是构造函数的另一种写法
- 类有原型对象
- 类原型对象的constructor指向类本身
- 类可以通过原型对象添加方法
- 类创建的实例对象有
__proto__原型指向类的原型对象 - 可以认为类是语法糖
ES5新增函数
// foreach 遍历数组
var arr = [1, 2, 3]
arr.foreach(function(value, index, array) {
console.log(value); // 每个数组元素 => 1 2 3
console.log(index); // 每个数组元素的索引号 => 0 1 2
console.log(array) // 数组本身 => [1,2,3] [1,2,3] [1,2,3]
})
// filter 筛选数组
var arr = [12, 66, 4, 88]
var newArr = arr.filter(function(value, index) {
return value > 20;
})
console.log(newArr); //=> [66, 88]
// some 查找数组中是否有满足条件的元素
// 如果找到第一个满足的元素就终止循环退出
var arr = [10, 30, 4]
var flag = arr.some(function(value) {
return value < 3;
})
console.log(flag) // => false
//foreach里面用return不会终止查找,但是some会
//trim 去除字符串两边的空格
var str = ' an dy '
var str1 = str.trim();
console.log(str1) // => 'an dy'
Object.keys
- 获取对象自身所有属性
var obj = {
id: 1,
pname: '小米',
price: 1999,
num: 2000
};
var arr = Object.keys(obj);
console.log(arr); // => ["id", "pname", "price", "num"]
Object.definePropety
object.definePropety() 定义新属性或修改原来的属性
Object.definePropety(obj, prop, descriptor)
Object.definePropety() 第三个参数descriptor说明:对象,以{}形式书写
- value:设置属性的值,可以为undefined
- writable: 值是否可以重写,true|false ,false 默认
- enumerable:目标属性是否可以被枚举,true|false false默认
- configurable: 目标属性是否可以删除或是否可以再次修改特性 true|false 默认为false
Object.defineProperty(obj, 'address', {
value: 'myAddress',
// 如果只为false 不允许修改这个属性值 默认值也是false
writable: false,
// enumerable 如果值为false 则不允许遍历, 默认的值是 false
enumerable: false,
// configurable 如果为false 则不允许删除这个属性 不允许在修改第三个参数里面的特性 默认为false
configurable: false
});
本文详细探讨了JavaScript中的原型链、继承机制,包括ES6类的继承、new操作符的本质、静态成员对象和原型对象的作用。通过实例解析了如何通过构造函数和原型对象实现继承,并介绍了ES5新增的Object.keys和Object.defineProperty方法。此外,还阐述了类的本质和原型链的工作原理,以及如何通过原型链实现方法的共享。

被折叠的 条评论
为什么被折叠?



