Javascript面向对象

44 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情

对象

在ECMAScript-262中,对象被定义为 “无序属性的集合,其属性可以包含基本值,对象或者函数”

 // 这里的person就是一个对象
 var person = {
     name: 'Tom',
     age: 18,
     getName: function() {},
     parent: {}
 }

创建对象的方式

 var obj = new Object();
 var obj = {};

工厂模式

工厂模式就是提供一个模子,然后通过这个模子复制出需要的对象。

 var createPerson = function(name, age) {
 ​
     // 声明一个中间对象,该对象就是工厂模式的模子
     var o = new Object();
 ​
     // 依次添加我们需要的属性与方法
     o.name = name;
     o.age = age;
     o.getName = function() {
         return this.name;
     }
 ​
     return o;
 }
 ​
 // 创建两个实例
 var perTom = createPerson('TOM', 20);
 var PerJake = createPerson('Jake', 22);

缺点

无法识别对象实例的类型。

函数无法复用;

 var obj = {};
 var foo = function() {}
 ​
 console.log(obj instanceof Object);  // true
 console.log(foo instanceof Function); // true

构造函数

首字母大写只是我们约定的小规定,用于区分普通函数;

new关键字改变this的指向;

解决判断实例与对象的关系。

 var Person = function(name, age) {
     this.name = name;
     this.age = age;
     this.getName = function() {
         return this.name;
     }
 }
 ​
 var p1 = new Person('Ness', 20);
 console.log(p1.getName());  // Ness
 ​
 console.log(p1 instanceof Person); // true

原型

创建的每一个函数,都可以有一个prototype属性,该属性指向一个对象。这个对象就是原型。

每一个new出来的实例,都有一个__proto__属性,该属性指向构造函数的原型对象。

 // 声明构造函数
 function Person(name, age) {
     this.name = name;
     this.age = age;
 }
 ​
 // 通过prototye属性,将方法挂载到原型对象上
 Person.prototype.getName = function() {
     return this.name;
 }
 ​
 var p1 = new Person('tim', 10);
 var p2 = new Person('jak', 22);
 console.log(p1.getName === p2.getName); // true

image.png

Person.prototype.constructor === Person 【true】

image.png

构造函数的prototype与所有实例对象的__proto__都指向原型对象【Person.prototype】。而原型对象的constructor指向构造函数【Person】。

通过Prototype共享的方式,实例就可以访问到构建函数的方法。

prototype提供共享的方法或者属性。

 function Person() {}
 ​
 Person.prototype = {
     constructor: Person,
     getName: function() {},
     getAge: function() {},
     sayHello: function() {}
 }

原型链

原型对象其实也是普通的对象。几乎所有的对象都可能是原型对象,也可能是实例对象,而且还可以同时是原型对象与实例对象。

 function add() {}
 // add构造函数
 add.prototype.constructor === add
 // add实例
 add.__proto__ ===  Function.prototype
 ​
 //Function构造函数
 Function.protoype.constructor === Function
 // Function 实例
 Function.__proto === Function.prototype
 // Function原型对象
 Function.prototype.__proto__ === Object.prototype
 ​
 // object构造函数
 object.prototype.constructor === Object
 object.__proto__ === Function.prototype
 // object原型对象
 object.prototype.__proto__ === null

这样我们就可以访问到Object上定义的原始方法,例如toString、valueof。基于原型链的特性,就可以实现继承。【原型链继承】

总结

从创建一个对象开始,new关键字创建对象、工厂模式、原型和原型链。这里边还可以展示,例如new关键字,它内部是怎么进行this转换的?