重学前端面向对象及其原型(二)

重学前端(二)

  • 运行时类型是代码实际执行过程中我们用到的类型。所有的类型数据都会属于7个类型之一。从变量、参数、返回值到表达式中间结果,任何JavaScript代码运行过程中产生的数据,都具有运行时类型。

类型

  • Undefined
  • Null
  • Boolean
  • String
  • Number
  • Symbol
  • Object
Undefined Null
  • Undefined类型表示未定义,他的类型只有一个值,就是undefined.任何变量在赋值前是Undefined类型、值为undefined,一般我们可以用全局变量undefined(就是名为undefined的这个变量)来表达这个值,或者void运算来把任意一个表达式变成undefined
  • Null类型也只有一个值,就是null,表示为控制,与undefined不同
String
  • String用于表示文本数据,最大长度为2^53 - 1
Number
  • Number类型基本符合IEEE 754-2008规定的双精度浮点数规则,根据浮点数的定义,非整数的Number类型无法用 **== (===也不行)**来比较

    • 0.1 + 0.2 == 0.3 //输出 false
      
    • 正确的比较方法:使用JavaScript提供的最小精度值

    • Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON
      
  • NaN,占用了 9007199254740990,这原本是符合IEEE规则的数字;

  • Infinity,无穷大;

  • -Infinity,负无穷大。

  • JavaScript中有+0 和 -0 ,在假发类运算中它们没有区别,单数触发的场合则需要特别留意区分**,‘忘记检测除以-0,而得到负无穷大’**的情况经常会导致错误,而区分+0 和 -0 的方式,正式检测 1/x 是 infinity还是-infinity

Symbol
  • SymbolES6中引入的新类型,它是一切非字符串的对象key的集合,在ES6中,整个对象系统被用Symbol
Object
  • 对象的定义是‘属性的集合’。属性分为数据属性和访问器属性,二者都是key-value结构,key可以是字符串或者Symbol类型
  • JS中的类仅仅是运行时对象的一个私有属性,而JS中时无法自定义类型的,在js的几个基本类型中,都在对象类型中有一个亲戚
    • Number
    • String
    • Boolean
    • Symbol
  • 所以,3 和 new Number(3)是完全不同的值,它们是一个Number类型,一个是对象类型,NumberStringBoolean,三个构造器是俩用的,当跟new搭配时,它们产生对象,当直接调用的时候,它们表示强制类型转换
  • .(点)运算符提供了装箱操作,它会根据基础类型构造一个临时对象,使得我们能在基础类型上调用对应对象的方法
装箱转换
  • 每一种基本类型NumberStringBooleanSymbol在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象,他是类型转换中一种相当重要的种类
拆箱转换
  • 在JavaScript标准中,规定了 ToPrimitive函数,它是对象类型到基本类型的转换(即,拆箱转换)。
  • 对象到 String 和 Number 的转换都遵循“先拆箱再转换”的规则。通过拆箱转换,把对象变成基本类型,再从基本类型转换为对应的 String 或者 Number。
  • 拆箱转换会尝试调用 valueOf 和 toString 来获得拆箱后的基本类型。如果 valueOf 和 toString 都不存在,或者没有返回基本类型,则会产生类型错误 TypeError。
总结
  • List 和 Record: 用于描述函数传参过程。
  • Set:主要用于解释字符集等。
  • Completion Record:用于描述异常、跳出等语句执行过程。
  • Reference:用于描述对象属性访问、delete等。
  • Property Descriptor:用于描述对象的属性。
  • Lexical Environment 和 Environment Record:用于描述变量和作用域。
  • Data Block:用于描述二进制数据。
JavaScript对象的特征
  • 对象具有唯一标识性:即使完全相同的俩个对象,也并非同一个对象
  • 对象有状态:对象具有状态,同一对象可能处于不同状态之下
  • 对象具有信鸽网i:季对象的状态,可能因为它的行为产生变迁

(一)具有唯一标识性

  • 各种语言的对象唯一标识性都是用内存地址来体现的,对象具有唯一表示的内存地址,所以具有唯一的标识

(二)第二 和 第三特征

  • JS中,将状态和行为统一抽象为‘属性’,考虑到JavaScript中函数设计成一种特殊对象

  • 下面代码就展示了 普通属性 和 函数作为属性的一个例子,其中 o是对象,d是属性,而函数f也是一个属性,尽管写法不太相同,但是对JavaScript来说,df就是俩个普通属性

  • var o = {
    	d:1,
    	f(){
    		console.log(this.d)
    	}
    }
    
JavaScript中对象独有的特色是:对象具有高度的动态性,这是因为JS赋予了使用者在运行是为对象添加状态和行为的能力
  • 为了提高抽象能力,JavaScript的属性被设计成比别的语言更加复杂的形式,它提供了 数据属性和访问器属性(getter / setter)俩类
JavaScript对象的俩类属性
数据属性具有四个特征
  • value:就是属性的值
  • writable:决定属性能否被赋值
  • enumerable:决定for in能否枚举该属性
  • configurable:决定改属性能否被删除或者改变特征值
访问器(getter / setter)属性
  • getter:函数 或者 undefined,在取属性值时被调用
  • setter:函数 或者 undefined,在设置属性值时被调用
  • enumerable:决定for in能否枚举该属性
  • configurable:决定该属性能否被删除或者改变特征值

访问器属性是的属性在读和写时执行代码,它允许使用者在写和堵属性时,得到完全不同的值,它可以是为一种函数的语法糖

我们通常用于定义属性的代码会产生数据属性,其中的writableenumerableconfigurable都会默认true, 我们可以使用内置函数 Object.getOwnPropertyDescripter来查看

JavaScript对象的具体设计:具有高度动态性的属性集合
JavaScript得原型
  • 如果所有对象都有私有字段[[prototype]],就是对象的原型
  • 读一个属性,如果对象本身没有,则会继续访问对象的原型,知道原型为空或者找到为止,(原型链)
ES6,JS提供了一系列内置函数,以便更为直接的访问操纵原型
  • Object.create根据指定的原型创建新对象,原型可以是null;
  • Object.getPrototypeOf获得一个对象的原型;
  • Object.setPrototypeOf设置一个对象的原型。
早期版本中的类与原型
  • ‘类’的定义是一个私有属性[[class]],语言标准为内置类型诸如NumberStringDate等指定了[[class]]属性,以表示它们的类。语言使用者唯一可以访问[[class]]属性的方式是Object.prototype.toString

  •     var o = new Object;
        var n = new Number;
        var s = new String;
        var b = new Boolean;
        var d = new Date;
        var arg = function(){ return arguments }();
        var r = new RegExp;
        var f = new Function;
        var arr = new Array;
        var e = new Error;
        console.log([o, n, s, b, d, arg, r, f, arr, e].map(v => 	Object.prototype.toString.call(v))); 
      
      //输出
      (10) ["[object Object]", "[object Number]", "[object String]", "[object Boolean]", "[object Date]", "[object Arguments]", "[object RegExp]", "[object Function]", "[object Array]", "[object Error]"]
    0: "[object Object]"
    1: "[object Number]"
    2: "[object String]"
    3: "[object Boolean]"
    4: "[object Date]"
    5: "[object Arguments]"
    6: "[object RegExp]"
    7: "[object Function]"
    8: "[object Array]"
    9: "[object Error]"
    length: 10
    __proto__: Array(0)
    
new运算接受一个构造器 和一组调用参数,实际上做了几件事
  • 以构造器的prototype属性(注意与私有字段[[prototype]]的区分)为原型,创建新对象
  • this和调用参数传给构造器,执行
  • 如果构造器返回的时对象,则返回,否则返回第一步创建的对象
JavaScript中的对象分类
  • 宿主对象(host Objects):由JavaScript宿主环境提供的环境,它们的行为完全由宿主环境决定
  • 内置对象(Built-in Object):由JavaScript语言提供的对象
    • 内置对象(intrinsic Objects):由标准规定,随着JavaScript运行时创建而自动创建的对象实例
    • 原生对象(Native Object):可以由用户通过ArrayRegExp等内置构造器或者特殊语法创建的对象
    • 普通对象(Ordinary Objects):由{}语法、Objects构造器或者class关键字定义类创建的对象,它能够被原型继承
宿主对象
  • 浏览器环境中的宿主,全局对象时windowwindow上又有很多属性,比如document,实际上这个全局对象window上的属性,一部分来自于JavaScript语言,一部分来自于浏览器环境
  • 宿主对象也分为固有的和用户可创建的俩种,比如document.createElement就可以创建一些dom对象,宿主也会提供一些构造器,比如我们可以使用 new Image来创建img对象
内置对象-固有对象
  • 固有对象是由标准规定,随着JavaScript运行时创建而自动创建的对象实例,固有对象在任何JS代码执行前就已经被创建出来了。
内置对象-原生对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5EcAR0pB-1581861071709)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200123193705440.png)]

  • 通过这些构造器,我们可以用new运算创建薪得对象,所以我们把这些对象称作为原生对象
  • 这些构造器创建的对象多数使用了私有字段,例如:
    • Error: [[ErrorData]]
    • Boolean: [[BooleanData]]
    • Number: [[NumberData]]
    • Date: [[DateValue]]
    • RegExp: [[RegExpMatcher]]
    • Symbol: [[SymbolData]]
    • Map: [[MapData]]
用对象来模拟函数与构造器:函数对象与构造器对象
  • 函数对象的定义是:具有[[call]]私有字段的对象,构造器对象的定义是:具有私有字段[[construct]]的对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值