JavaScript一切都是对象

  • 为什么说JavaScript一切都是对象?
  • 字面量与构造函数从设计模式的角度如何抉择和处理可能引发的问题?

 一、为什么说JavaScript一切都是对象?

 1.1所有类型都有对应的对象模式

let str = "abc";
let strObj = new String("abc");

1.2无论是原始值类型还是引用值类型,都可以按照对象的方式调用该类型原型上的方法和属性。

 

1.3函数执行时的上下文关系也是基于闭包的对象模型,然后通过原型链的关系为任务提供计算环境,详细参考:Javascript的作用域和闭包(一)

1.4数组也是基于对象拓展的有序列表结构,最直观的就是通过typeof检查数组类型为“object”。

1.5函数执行时参数也会被包装成一个类数组。

 二、JavaScript弱类型语言成就了其一切都是对象的特性

所谓弱类型语言,就是变量的类型不是由变量自身决定的,而是由变量的值所决定的。

由于变量类型是由值决定,那么在执行计算时变量就必须告知执行任务的主体当前所参与计算的值时什么类型,由此变量就必须提供两个属性:值、类型。所以,这才是一切都是对象的根源。

这就是弱类型和强类型语言的差别,在强类型语言中其类型是变量本身固定的特性,如果出现计算值与变量的类型不匹配就会报错,而是不像JS这样尽可能的通过类型转换保证程序的正常执行。像JAVA这样的强类型语言如果发生值与变量的类型不匹配在编译时就会发生错误,这种天然的强壮性也是强类型语言相对弱类型语言的优势,但我们当前讨论的时JavaScript设计模式,也就是我们如何在JavaScript这种由于弱类型特性导致的强制类型转换等不确定性的环境下设计出可靠的程序。

在弱类型语言的环境下,为了体现出原始值类型和引用值类型的区别,当我们读取变量时原始值类型直接返回变量值,而引用值类型返回整个值的引用对象,由此我个人的理解是:

本质上所有值都是一个对象,但是为了体现出原始值的特性,将原始值的读写直接作用在对象的value属性上,这样就实现了直观的原始值变量赋值的书写方式。

从这样的一个逻辑推导下,为了使弱类型变量必须具备的两个属性在编程时并不需要人为的实现,而是同强类型语言一样直接使用值的字面量值观的编程范式实现,但其编译过程本质上会发生一次对象构造。

所以,在JavaScript中原生的构造函数就是每一次赋值都会发生的显性表达,但又同时可以基于这样一个构造函数拓展构造特性岂不是一举两得的事情,所以在这样的逻辑前提下,任何赋值操作都建议直接使用字面量形式,除非需要拓展其他赋值特性的操作。

字面量与设计模式:可以保证程序的可读性、可靠性。

构造模式与设计模式:可以提高程序的重用性和可维护性。

 2.1基于大驼峰命名约定实现自定义构造函数

function FunStr(str){
    let index = str.indexOf("国粹");
    if(index > -1){
        return str.substring(0,index) + "**" + str.substring(index + 2);
    }
    return str;
}

示例中构造的是字符串,这个构造函数不能使用new字符来执行,这与內置的构造函数有类似的功能(基本值类型包装器),比如String()。但这种方式一定要标准化到开发文档中,不要私自任意使用,否则可能会导致其他协同开发者无法正确的使用该构造函数,这种模式也叫做自调用构造函数。

2.2关于字面量的可靠性,可以参考《JavaScript模式》p51数组构造函数的特殊性,在很多时候內置构造函数相对字面量而言会出现很多意想不到结果,书中的数组构造函数就是最典型的一种。

2.3JSON字符中不能使用函数和正则表达式。

 

posted @ 2021-12-14 11:48  他乡踏雪  阅读(220)  评论(0编辑  收藏  举报