美文网首页
面向对象

面向对象

作者: 海山城 | 来源:发表于2017-11-29 23:31 被阅读0次

理解对象

JS 中的对象是一系列无序 key: value 的集合

var obj = { a: 1, b: 2}
var person = {
    name: 'hunger',
    printName: function(){
        console.log('My name is hsc')
    }
}

但假设我们定义一个函数

function sum(a, b){
    return a + b
}

console.log(sum.name)   // => sum
console.log(sum.length)  //2

会发现,函数 sum也有很多属性,从这个角度看,函数也是 js 对象的一种

构造对象

(1) 通过字面量来构造一个对象
这种方法缺点很明显:
太麻烦了,每次构建一个对象都是复制一遍代码

var obj1 = {
    name: 'Byron',
    age: 20,
    printName: function(){
        console.log(obj1.name);
    }
}
var obj2 = {
    name: 'Casper',
    age: 25,
    printName: function(){
        console.log(obj2.name);
    }
}

(2) 使用函数做自动化
这种方法解决了上一种的代码重复的问题,但是这种方法还是不够完美。这种方式构造出来的对象类型都是Object,没有识别度。并且每个对象都有一个相同的printName方法,造成了内存的浪费

function createObj(name, age)
{
  var obj = {
    name: name,
    age: age,
    printName: function(){
      console.log(this.name)
    }
  }
  return obj
}
var obj = createObj('hsc', 25)
obj.printName()

(3) 通过new运算符来构造函数,返回一个对象实例

function Person(name, age){
    this.name = name;
    this.age = age;
    this.printName = function(){
            console.log(this.name);
    }
}
var p1 = new Person('Byron', 25);
var p2 = new Person('HSC', 30);

这种方式创建对象首先需要了解几个知识点

  • new 运算符接受一个函数 F 及其参数:new F(arguments...)
  • function作为构造函数(通过new操作符调用)的时候会返回一个类型为function的name的对象
  • 前面说过函数也是一个对象,function有个constructor的属性指向其本身

那么,通过new运算符构造函数从而创建出一个对象的过程具体如何实现的呢?即var p1 = new Person('Byron', 25)具体发生了什么呢?
①创建一个空对象。空对象的 proto 属性被浏览器自动设置为 F.prototype (具体参考原型和原型链的介绍)
②初始化该对象。函数 F 被传入参数并调用,关键字 this 被设定为该空对象,可按照下面理解

function Person(name, age){
    var this = {};
    this.name = name;
    this.age = age;
    this.sayName = function(){
            console.log(this.name);
    }
    return this
}
var p1 = new Person('Byron', 25);
var p2 = new Person('HSC', 30);

③返回赋值完成的对象
注:在函数中return 基本类型,构造函数时。没有影响,但是return一个对象时,就会有影响。如下

function Person(name, age){
    this.name= name;
    this.age = age;
    return 1 //情况①
    return {a:1,b:2} //情况②
}
var p1 = new Person('Byron', 25); //情况①结果: p1{name:"Byron", age:25}
var p1 = new Person('Byron', 25); //情况②结果: p1{a:1,b:2}

这种方法构建的对象具有识别度,为什么这么说呢?先来看一看instanceof这个操作符,它可以判断对象是否为某个函数的实例。注意instanceof判断的是对象(1 instanceof Number 结果是false)

p1 instanceof Person  //true
p1 instanceof Object   //true
p1 instanceof Animal  //false

可见通过new构造出来的对象,是属于创建它的函数的一个实例。这个创建实例的函数就是js中的类
识别度的问题是解决了,可是这样构建对象,同样每个对象都有相同的printName方法,造成了内存的浪费,这就要提到prototype(原型)了。
每个函数内部都有一个prototype对象,实例调用方法(p1.printName())时,会先去自身找有没有这个方法,找不到,会自动去__proto__中找,也就是F.prototype中找。这样重复的方法(比如printName)等可以放到F.prototype中(原型,相当于一个公共容器),可以减少内存的浪费。
所以最终的代码可以改成这样

function Person(name,  age){
    this.name = name;
    this.age = age;
}
Person.prototype.printName = function(){
  console.log(this.name);
}
var p1 = new Person('Byron', 25);
var p2 = new Person('HSC', 30);

注:公共容器中的函数中的this也是指的是调用该函数的对象(所以p1.printName输出的是Byron,而p1.__proto__.printName输出的是undefined,因为p1.__proto__(即Person.portotype)并没有name属性)
所以,现在知道了通过new F 来构造对象是最好的了吧!

相关文章

  • PHP全栈学习笔记8

    面向对象的基本概念,面向对象编程,oop,面向对象,面向对象的分析,面向对象的设计,面向对象的编程,什么是类。 类...

  • PHP全栈学习笔记8

    面向对象的基本概念,面向对象编程,oop,面向对象,面向对象的分析,面向对象的设计,面向对象的编程,什么是类。 类...

  • 总结.Net基础知识——献给即将入坑的同行们(一期)

    什么是面向对象 面向对象OO = 面向对象的分析OOA + 面向对象的设计OOD + 面向对象的编程OOP; 通俗...

  • 面向对象基础

    面向对象编程包括: 面向对象的分析(OOA) 面向对象的设计(OOD) 面向对象的编程实现(OOP) 面向对象思想...

  • 20-OOP类与对象

    面向对象 Object Oriented 学习面向对象:XXOO 面向对象的学习: 面向过程和面向对象的区别: 面...

  • JavaScript面向对象核心知识归纳

    面向对象 概念 面向对象就是使用对象。面向对象开发就是使用对象开发。 面向过程就是用过程的方式进行开发。面向对象是...

  • 面向对象(未完成)

    面向对象 标签(空格分隔): 面向对象 第一章:面向对象(上) 什么叫面向对象 面向过程、面向对象、两者区别 构造...

  • 面向对象:创建对象&继承

    博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...

  • 面向对象

    了解什么是面向对象 首先,我们学习面向对象,要了解什么是面向对象,面向对象的重要概念:类,对象。 面向对象提出的这...

  • 面向对象的三大基本特征和五大设计原则

    1、面向对象概念 1.1、理解面向对象 面向对象是相对面向过程而言; 面向对象和面向过程都是一种思想; 面向过程:...

网友评论

      本文标题:面向对象

      本文链接:https://www.haomeiwen.com/subject/tfovpxtx.html