JavaScript 笔记
1 原型
1.1 原型的概念
- 任何一个对象,都有原型。原型也是个对象。
- 对象可以继承原型上的属性(方法)。
1.2如何获取对象的原型
① 隐式原型方式
对象.__proto__
② 显式原型方式
对象的构造函数.prototype
**注意:**具有相同构造函数的两个对象,原型也是一致的。
1.3 对象、构造函数、原型之间的关系
① 对象和构造函数
- 构造函数是对象的抽象(描述),对象是构造函数的实例。
- 一个构造函数可以创建多个对象,但是一个对象只能有一个构造函数。
② 对象和原型
- 每个对象都有原型。
- 每个对象都可以使用原型上的属性(方法)。
③ 构造函数和原型
- 构造函数通过属性
prototype
可以获得构造函数的实例的原型。 - 具有相同构造函数的对象,原型也是一致的 。
1.4 自定义构造函数时原型对的应用
// 自定义构造函数
function User(name, age, address) {
// 设置对象的属性
this.name = name;
this.age = age;
this.address = address;
}
// 把对象上的方法设置到对象的原型
User.prototype.getInfo = function() {
console.log('我叫'+this.name+',我的年龄'+this.age+',我住在'+this.address);
};
User.prototype.addShopcart = function() {
console.log(this.name + '向购物车添加了商品');
}
1.5 判断属性是否属于对象本身
对象.hasOwnProperty("属性名");
规则:
1、hasOwnProperty() 判断,只有在对象本身上的属性才返回true,在原型上的和不存在的属性,返回false。
2、
in
运算符,对象本身和原型上的属性都返回true,只有不存在的属性才返回false。
1.6 创建对象的同时指定原型
// 自定义构造函数
function User(name, age, address) {
// 设置对象的属性
this.name = name;
this.age = age;
this.address = address;
}
// 把对象上的方法设置到对象的原型
User.prototype.getInfo = function() {
console.log('我叫'+this.name+',我的年龄'+this.age+',我住在'+this.address);
};
User.prototype.addShopcart = function() {
console.log(this.name + '向购物车添加了商品');
}
2 原型链
2.1 原型链的概念
每个对象都有原型,原型还是对象,所以原型也有原型,一直到一个没有原型的对象(顶层原型),组成了一个原型链。
2.2 属性查找过程
当时用对象中某个属性的时候:
1、先从对象自身查找,如果有该属性直接返回,如果没有该属性从原型上进行查找。
2、如果原型上查到了该属性,直接返回;如果原型也没有该属性,继续从原型上进行查找。
3、一直查找到顶层原型对象,哪里找到哪里停止,最后顶层原型也没有属性,返回undefined。
2.3 构造函数和原型链
1、数组的原型、数字的原型、字符串的原型、自定义构造函数创建的实例的原型,都是Object 的实例。
2、最顶层的原型对象是 Object.prototype
3、原型对象上constructor 属性指向的并不是自己的构造函数,指向的是以该原型对象为原型的对象的构造函数。
3 值类型和引用类型
3.1 值类型和引用类型的概念
原始类型, 也叫值类型, 还可以被称为不可变类型。
对象类型,也叫引用类型,还可以被称为可变类型。
3.2 值类型和引用类型的存储方式
1、变量和原始类型的数据存储在内容的栈结构中,对象类型的数据存储到内容的堆结构中。
2、变量的值如果是原始类型,变量和值都在栈结构中;如果变量的值是对象类型,对象存在堆结构中,栈结构中存的是变量和对象的地址。
3、如果变量a 赋值到 变量b , 变量a 的值如果是原始类型,直接把值给b 。变量a 的值如果是对象类型,把地址给 b , 导致a 和 b 指向的是一个对象。
4、原始类型的赋值方式成为值传递;对象类型的赋值方式成为引用传递。
3.3 不可变 和 可变
不可变类型:原始类型的数据,无法修改数据中的一部分,一个原始类型的数据必须作为一个整体。
可变类型:对象类型的数据,可以修改数据中的一部分(修改属性、修改元素)。
3.4 内置的构造函数和自定义的构造函数在引用传值和原型的区别:
如果改了自定义的构造函数的prototype ,随后创建出来的实例会受到影响。而内置的构造函数改变prototype 后, 对后面创建的实例没有影响,原型该是谁还是谁。