一、创建对象有几种方法
- 字面量创建对象
1-1. 什么是字面量
字面量就是所见即所,指的是常量;用来为变量赋值时的常数量
代码例子:123;‘ABC’, {name: ‘张三’}, undefined , true
生活例子:门店的招牌,手机号,身份证,排队号
1-2 字面量对象: 通过字面量的方式创建对象
let o1 = {name: '张三', age: 22}
// 生活例子: 一个叫张三的对象
- Object 方法创建对象
2-1 Object方法将输入的参数转换为对象
① null 和 undefined 返回空对象
② 数字返回数字类型的对象;字符串返回字符串类型对象;函数返回函数对象
③ 参数如果是对象,返回参数本身
生活例子:Object方法类似于分类,你把任意物品给到某个人或机器,然后他会对物品分类,
比如 给香蕉,水果:香蕉;菠菜, 蔬菜:菠菜,薯片,零食:薯片
2-2 Object 方法创建对象
let o2 = new Object({name: '菠菜'})
// 生活例子:一个名叫菠菜的对象
- 构造函数创建对象
3-1 什么是构造函数
用 new 关键字来调用的函数,称为构造函数。构造函数首字母一般大写
let M = function () {
this.name ='243'
}
// 普通函数
console.log(M)
ƒ () {
this.name ='243'
}
// new M()构造函数 , 构造函数返回函数内部的对象,如果内部有定义属性,返回内部属性对象,如没有返回空对象
console.log(new M())
M {name: '243'}
3-2 用构造函数创建对象
let M = function () {
this.name = '张三'
}
let o3 = new M()
o3
M {name: '张三'}
- Object.create创建一个新对象
静态方法以一个现有对象作为原型,创建一个新对象
var P = {name: 'o4'}
var o4 = Object.create(P)
o4
{}
二、原型、构造函数、实例、原型链
let M = function () {
this.name = '张三'
}
let o3 = new M()
- 构造函数: 普通函数被new 使用后,就是构造函数, M就是构造函数
- 实例:任意对象就是一个实例,上述o1、o2、o3、o4都是实例
- 构造函数可以通过 new运算符 生成一个实例,例如o3
- 构造函数也是函数,所有函数上都有prototype属性(函数声明时自动生成),构造函数的prototype属性指向原型对象(初始化空对象)
- 原型对象 的构造器 constructor 默认指向声明的构造函数,
M.prototype.constructor === M
true
- 实例的__proto__属性指向M构造函数的原型对象
o3.__proto__===M1.prototype
true
7. 原型链:创建一个实例对象,通过实例对象的__proro__属性找创建实例的原型对象,一直往上找,直到找到构造函数Object.prototype 原型对象,原型链的顶点为null, 这个链条就是原型链
o5.__proto__.__proto__ === Object.prototype
true
o5.__proto__.__proto__.__proto__
// null
- 原型对象增加属性和方法,都可以被实例所继承,所以当多个实例有相同的方法就可以存在原型对象上
let M = function (name) {
this.name = name
}
let o3 = new M()
M.prototype.say = function () {
console.log('你好')
}
o3.say()
// 你好
- 构造函数的__proto__属性 等于 函数的原型对象
M.__proto__ === Function.prototype
三、instanceof的原理
instanceof : 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
// o3 是 M构造函数的一个实例
o3 instanceof M
true
// o3 是原型链上构造函数的实例
o3 instanceof Object
true
// M的原型对象的__proto__ === Object的原型对象
M.prototype.__proto__ === Object.prototype
true
// o3的__proto__的构造器 === M,表示o3由M构造函数直接生成
o3.__proto__.constructor === M
true
// o3的__proto__的构造器 不等于Object,表示o3不是由Object 构造函数直接生成
o3.__proto__.constructor === Object
false
四、new运算符
new 运算符的工作原理:
let M = function (name) {
this.name = name
}
let o3 = new M()
- new 的第一个步骤,一个新对象被创建
- 新对象继承构造函数的原型对象, var o3 = new M(), o3 继承 M.prototype 上的方法和属性
- 构造函数M被执行。 执行的时候,相应的参数会被传入,同时上下文(this)会被指定为这个新实例
PS:当构造函数不传递参数时, new M 等同于 new M() - 如果构造函数返回了一个对象,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象(空对象)
var new2 = function (func) {
// 步骤1和2
var o =Object.create(func.prototype)
// 步骤3
var k = func.call(o)
// 步骤4
if (typeof k === 'object') {
return k
} else {
return o
}
}
o6 = new2(M)
M {name: '张三'}
o6 instanceof M
true
o6 instanceof Object
true
o6.__proto__.constructor === M
true