JS面向对象编程

前言

Java ,JS 都是面向对象编程语言,但是它们的语法有重大区别。
Java 中有关键字 class ,用于定义类型。
JS 中没有定义类型的关键字,而是使用函数作为类,准确的说JS是基于原型的语言。

一、JS面向对象基础用法

// 相当于构造方法的函数
function makePerson(first, last) {
  return {
    first: first,
    last: last
  };
}
// 相当于功能方法
function personFullName(person) {
  return person.first + ' ' + person.last;
}
// 相当于功能方法
function personFullNameReversed(person) {
  return person.last + ', ' + person.first;
}

//相当于创建对象
var s = makePerson('Simon', 'Willison');
//相当于调用功能方法
personFullName(s); // "Simon Willison"
//相当于调用功能方法
personFullNameReversed(s); // "Willison, Simon"

这种方式定义了太多函数,太丑陋了。

二、JS面向对象一般用法

因为JS中函数也是对象,所以可以将函数附加到对象中。

function makePerson(first, last) {
  return {
    first: first,
    last: last,
    //功能方法
    fullName: function() {
      return this.first + ' ' + this.last;
    },
    //功能方法
    fullNameReversed: function() {
      return this.last + ', ' + this.first;
    }
  };
}

var s = makePerson('Simon', 'Willison');
//调用功能方法
s.fullName(); // "Simon Willison"
s.fullNameReversed(); // "Willison, Simon"

注意this关键字,指向当前对象。
如果使用一个对象 obj 的 . 或 [] 操作符调用该函数,this 就是 obj 。
如果没有用 . 或 [] 调用该函数, this 就是 global。

var s = makePerson('Simon', 'Willison');
var fullName = s.fullName;
fullName(); // undefined undefined  此处 this是 global,而global没有 first和last变量。

三、JS面向对象二般用法

掌握 this 的使用,可以更进一步优化代码:

function Person(first, last) {
  this.first = first;
  this.last = last;
  this.fullName = function() {
    return this.first + ' ' + this.last;
  };
  this.fullNameReversed = function() {
    return this.last + ', ' + this.first;
  };
}
var s = new Person('Simon', 'Willison');

这种方式也存在问题:
在这里插入图片描述
创建每一个实例对象时,都会创建 fullName 和 fullNameReversed 函数对象,创建太多的函数对象,造成空间浪费。

四、JS面向对象三般用法

function personFullName() {
  return this.first + ' ' + this.last;
}
function personFullNameReversed() {
  return this.last + ', ' + this.first;
}
function Person(first, last) {
  this.first = first;
  this.last = last;
  this.fullName = personFullName;
  this.fullNameReversed = personFullNameReversed;
}

在这里插入图片描述
功能函数只创建了一次,创建实例对象时,没有重新创建功能函数,只是都引用了创建好的函数,节省了空间。

五、JS面向对象四般用法 - 原型

使用原型 prototype

function Person(first, last) {
  this.first = first;
  this.last = last;
}
Person.prototype.fullName = function() {
  return this.first + ' ' + this.last;
};
Person.prototype.fullNameReversed = function() {
  return this.last + ', ' + this.first;
};

Person.prototype 叫做 Person 的原型,它也是一个对象,共享给Person的所有实例使用。
prototype 组成了一个查询链,叫 “原型链”:
任意时刻访问Person的一个不存在属性时,JS都会去检查 Person.prototype 中有没有这个属性。

注意:分配给 Person.prototype 的数据将共享给它的所有实例对象 。

prototype 是一个非常强大的特性,可以在任何时候修改 prototype ,运行时给已有对象添加额外方法。

var s = new Person('Simon', 'Willison');
s.firstNameCaps(); // TypeError on line 1: s.firstNameCaps is not a function

Person.prototype.firstNameCaps = function() {
  return this.first.toUpperCase();
};
s.firstNameCaps(); // "SIMON"

神奇的是,JS的内建对象也可以通过 prototype 添加额外数据。

var s = 'Simon';
s.reversed(); // TypeError on line 1: s.reversed is not a function

String.prototype.reversed = function() {
  var r = '';
  for (var i = this.length - 1; i >= 0; i--) {
    r += this[i];
  }
  return r;
};

s.reversed(); // nomiS

reversed 函数对String字面量也可用了

'This can now be reversed'.reversed(); // desrever eb won nac sihT

六、原型链

prototype 原型模式构成了原型链,原型链的顶点是 Object.prototype。
比如说 Object.prototype 中拥有 toString() 函数,当获取对象表达式时会调用 toString() 函数。

var s = new Person('Simon', 'Willison');
s.toString(); // [object Object]

Person.prototype.toString = function() {
  return '<Person: ' + this.fullName() + '>';
}

s.toString(); // "<Person: Simon Willison>"

七、apply 和 call 函数

// func 是一个函数对象
// obj 将会作为 this 使用
// args 是调用 func 时传入的参数
func.apply(obj,args)

apply 的用法有点像 java 的反射,对象.方法 -> 方法.对象 。

// trivialNew用来模拟 new,但它不构造原型链,不能代替 new 
function trivialNew(constructor, ...args) {
  var o = {}; // Create an object
  constructor.apply(o, args);
  return o;
}

var bill = trivialNew(Person, 'William', 'Orange');
// 等价于
var bill = new Person('William', 'Orange');

apply 与 call 是一个姐妹函数,call 函数将展开表达式替换成了一个数组

// func 是一个函数对象
// obj 将会作为 this 使用
// argsArr 是调用 func 时传入的参数数组
func.call(obj,argsArr)
function lastNameCaps() {
  return this.last.toUpperCase();
}
var s = new Person('Simon', 'Willison');
lastNameCaps.call(s);
// Is the same as:
s.lastNameCaps = lastNameCaps;
s.lastNameCaps(); // WILLISON

八、new 关键字

new 与 this 有很强的联系。

// 1、new 先创建了一个空对象 {}
// 2、调用 Person()函数,this 设置给 创建的 {} 对象
// 3、Person()函数不返回值,作用仅仅是对 this 即 {} 进行修改
// 4、new 关键字返回 this 引用
var s = new Person('Simon', 'Willison');

用 new 关键字调用的函数叫做构造函数,构造函数通常首字母大写,用来提示人们使用 new 来调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值