博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入浅出面向对象和原型【概念篇2】
阅读量:6257 次
发布时间:2019-06-22

本文共 3144 字,大约阅读时间需要 10 分钟。

墙裂建议您在看这篇文章之前阅读一遍我之前写的文章 ,因为此篇文章涉及到不少相关概念都在上篇文章里啦

1.1 简单复习对象

对象是老生常谈的概念了,在这里我们来简单复习一下

var obj = {        a: 1,         b: "hello",        c: true,        d: function () {            console.log("hello")        },        e: {            e_1: "对象内储存一个对象"        }    }

对象是一个储存一系列无序 key: value【键值对】 的集合的容器

注意:核心是要将对象作为一个容器看待

使用对象作为容器的这个特性我们可以进行封装,这会产生两个好处

  1. 让我们的代码变得优雅、易读
  2. 规避全局变量

1.2 通过构造函数创建对象

1.2.1 关于function的额外知识

  1. function作为构造函数(通过new操作符调用)的时候会 返回 一个类型为function的对象
  2. function可以接受参数,可以根据参数来创建 相同类型不同值 的对象
  3. function实例作用域内有一个constructor属性,这个属性就可以指示其构造器

1.2.2 学会使用 new Function

new 运算符接受一个函数 F 及其参数:new F(arguments...)

  1. 创建类的实例——这步是把一个空的对象的__proto__属性设置为 F.prototype
  2. 初始化实例——函数 F 被传入参数并调用,关键字 this 被设定为该实例
  3. 返回实例
function People(name) {        this.name = name        this.sayName = function () {            console.log(name)        }        // 一般在这个函数里不要 return        // 如果return引用类型的话,等于把return的值赋值给p1    }    People() // this指向全局变量,name和sayName成为了全局变量的属性    var p1 = new People('sad')    // 第一步:instance = {} 创建了一个类的实例 —— 空对象,并且将空的对象的__proto__属性设置为 F.prototype,也就是说    // 第二步:执行函数People(),并传入参数"sad",并将this指向p1    // 第三步:return instance【实例】 , 即把instance赋值给p1    // 请注意 People()是一个函数,new People()是构造函数    var p2 = new People('angry')

1.2.3 instanceof

instance 的中文意思为 实例

那么 instanceof 自然就是用来判断对象是否为某个类型的实例

console.log(p1 instanceof People) // true    // 意思是判断 对象(p1)是否为某个类型(People)的实例    // p1 是由 People 构建出来的,自然是People的实例,返回为true

但需要注意的是,instanceof 运算符的工作原理是检测 类的prototype 是否存在实例的原型链上

console.log(p1 instanceof Object) // true    // 因为Object.prototype可以被实例p1以原型链的方式访问到

1.2.4 构造函数存在的问题

构造函数在解决了上面所有问题,同时为实例带来了类型

但可以注意到在上例中,每个的实例的方法作用是一样的
但是每个实例被创建的时候都要重新声明一遍,浪费了内存

// 我们再来看一下这个函数    function People(name) {        this.name = name        this.sayName = function () {            console.log(name)        } // 每个实例的sayName方法却是相同的,而且每出现一个新实例,都是新声明一个函数,大大地浪费了内存    }

能不能给People的实例都使用同一个sayName方法呢

1.3 构造函数&原型&原型链

1.3.1 构造函数

任何函数使用new表达式就是构造函数,也就是说这个函数成为了一个类

1.3.2 用原型链解决重复创建的问题

  1. 每个对象都会自带一个名称为prototype的属性
  2. prototype属性是一个对象
// 还是这个例子    function People(name) {        this.name = name        this.sayName = function () {            console.log(name)        }     }    var p1 = new People('sad')    var p2 = new People('angry')        // People本身就有prototype属性    console.log(People.prototype) // {constructor: ƒ}     // 而每个对象也都会带有一个__proto__属性,指向这个构造函数【实例】的类    // 所有的实例都共用一个prototype    console.log(p1.__proto__ === People.prototype) // true    console.log(p2.__proto__ === People.prototype) // true
// 实例可以通过__prop__访问到其 类 的prototype属性,这就意味着类的prototype对象可以作为一个公共容器,供所有实例访问。    People.prototype.test = "abc"    console.log(p1.test) // abc    // p1这个对象没有test属性,但是可以通过它的__proto__属性访问到People的prototype属性
上述关系我们用一张图来帮助大家更好地理解

clipboard.png

1.3.3 解决内存浪费问题

由上我们可以知道

  1. 所有实例都会通过原型链引用到其类的prototype
  2. prototype相当于所有实例都可以访问到的一个公共容器,这个公共容器也是这些实例的类的属性

    那么如何解决内存浪费问题呢?

    Answer:重复的东西移动到公共容器里就可以了

function People(name) {        this.name = name // 每个对象的name属性时不同的,这点无可厚非    }    People.prototype.sayName = function () {        console.log(this.name)    } // 将sayName方法放入People的原型中    var p1 = new People('sad')    var p2 = new People('angry')    console.log(p1.sayName())    console.log(p2.sayName())

转载地址:http://sqnsa.baihongyu.com/

你可能感兴趣的文章
两列布局之左边固定宽度,右边自适应(绝对定位实现方法)
查看>>
4,gps信号与地图匹配算法
查看>>
python print的用法
查看>>
之字形打印矩阵
查看>>
我的世界之电脑mod小乌龟 —— 方位上的操作 lua函数集
查看>>
游戏方案
查看>>
在 Linux 下搭建 Git 服务器
查看>>
StackExchange.Redis Client(转载)
查看>>
Leetcode题目:Bulls and Cows
查看>>
bk. 2014.12.1
查看>>
CEOI2014 wall Spoiler
查看>>
UVA10391 ZOJ1825 Compound Words【SET+暴力】
查看>>
动态规划------Combination Sum IV
查看>>
[BZOJ2463][中山市选2009]谁能赢呢?
查看>>
iOS数据持久化存储之属性列表
查看>>
最后冲刺时间
查看>>
前端开发薪资之各地区对比(图文分析)
查看>>
jquery简单的大背景banner图片全屏切换
查看>>
java疑问
查看>>
JAVAEE 介绍
查看>>