对象 面向对象 原型对象 原型链

151 阅读3分钟

对象

什么是对象

  • 在JavaScript中,一切皆对象

如何创建一个对象

字面量形式

var obj = {}

构造函数(普通函数的写法,一般用首字母大写开头,用于区分构造函数和普通函数)(内部关键字this关键词)(关键字 new实例化一个对象)

// 构造函数
function Person(name){
    this.name = name
    this.say = ()=>{
        console.log('I am ' + this.name);
    }
}
// 通过new关键字实例化一个对象
const person1 = new Person('wu')
console.log(person1.name); //wu
person1.say()//I am wu

使用构造函数注意

  • new 一个对象的过程 let man = new Person()
  1. 首先创建一个新的对象 var obj = {}
  2. 接着将空对象的__proto__指向构造函数的原型对象prototype obj.__proto__= Person.prototype
  3. 再接着将this指向空对象 Person.call(obj)
  4. 执行构造函数内部代码
  5. 最后将新对象返回
  • 使用构造函数的时候,更推荐在构造函数内部定义属性,在原型上定义方法
// 构造器及其属性定义

function Test(a,b,c,d) {
  // 属性定义
};

// 定义第一个方法

Test.prototype.x = function () { ... }

// 定义第二个方法

Test.prototype.y = function () { ... }

// 等等……

Object()构造函数

let stu1 = new Object()
stu1.name = 'hu'
stu1['age'] = 18
stu1.say = function(){console.log(this.name);}

let stu2 = new Object({
    name:'wei',
    say:function(){console.log(this.name);}
}) 

Object.create()

  1. 接受一个对象,为空报错
  2. 以某一个对象为原型对象,实例化一个新的对象出来
  3. 下边的例子say的方法(包括属性)是挂载在stu3的原型stu1上的(关于对象原型的后边会有讲解)
let stu3 = Object.create(stu1)
console.log(stu3);//{}
stu3.say() // hu

比较

通过 new 的方式创建对象和通过字面量创建有什么区别?

对于对象来说,其实都是通过new产生的。 更推荐字面量方式(无论是性能上还是可读性上) 通过new Object()方式 需要通过作用域链一层层找到Object,但是字面量方式不需要

面向对象的三大特征

  • 封装:将公共的属性和方法(行为)封装在一个对象中
  • 继承:子类可以继承父类的属性和方法
  • 多态:同一个方法具有不同的表现形式

原型对象与原型链

单次翻译

prototype -> 原型

官方定义

  • 原型对象:JavaScript 常被描述为一种基于原型的语言 (prototype-based language) ——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。
  • 原型链 (prototype chain) :原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain) ,它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

理解

  • 对象的原型(可以通过Object.getPrototypeOf(obj)或者已被弃用的__proto__属性获得)与构造函数的prototype属性之间的区别是很重要的。
  • 前者是每个实例上都有的属性,后者是构造函数的属性。
  • 也就是说,Object.getPrototypeOf(new Foobar())Foobar.prototype指向着同一个对象。
  • 总而言之就是,每一个对象都有__proto__属性,每一个函数都有prototype属性,然后实例化对象的__proto__指向他的构造函数的prototype属性(也就是原型对象)

原型链

原型链的顶端是null

Snipaste_2021-12-13_18-16-41.png