关于JS字面量及其相关的一些小知识点

字面量:用来为变量赋值时的常数量。

 

对象字面量

对象字面值是封闭在花括号对({})中的一个对象的零个或多个"属性名:值"列表。

var person={
    "name":"Jack",
    "age":29,
    5:true  // 这里的数值属性,不能使用传统的点访问符,需要使用数组访问符
}

console.log(person.name) // Jack
console.log(person[5]) // true
console.log(person.5) // Uncaught SyntaxError: missing ) after argument list
console.log(person.'5') // Uncaught SyntaxError: Unexpected string

除了数字之外,其它非法标识符例如 空格、感叹号甚至空字符串,都可以用于属性名称中,当然访问这些属性仍然只能用数组访问符。

在通过对象字面量定义对象时,实际上不会调用Object构造函数(Firefox 2及更早版本会调用Object构造函数;但Firefox3之后就不会了)。这是因为字面量法创建对象强调该对象仅是一个可变的hash映射,而不是从对象中提取的属性或方法。

 

增强性字面量支持

在es6中,对象字面量的属性名可以简写、方法名可以简写、属性名可以计算。例如:

var name = "nana", age = 20, weight = 78
var obj = {
    name, // 等同于 name: nana
    age, // 等同于 age: 20
    weight, // 等同于 weight: 78

    sayName() { // 方法名简写,可以省略 function 关键字
        console.log(this.name);
    },

    // 属性名是可计算的,等同于over78
    ['over' + weight]: true
}

console.log(obj) // {name: "nana", age: 20, weight: 78, sayName: ƒ, over78: true}

注意每个对象元素之间,需要以逗号分隔,每个元素没有字面上的键名,但其实也是一个键值对。

甚至在创建字面量对象时,可以使用隐藏属性__proto__设置原型,并且支持使用super调用父类方法:

var superObj = {
    name: "nana",
    toString(){
        return this.name 
    }
}
var obj = {
    __proto__: superObj,
    toString() {
        return "obj->super:" + super.toString();
    }
}
console.log(obj.toString()) // obj->super:nana

 属性赋值器(setter)和取值器(getter),也是采用了属性名简写:

var cart = {
    wheels: 4,
    get wheels () {
        return this.wheels
    },
    set wheels (value) {
        if (value < this.wheels) {
            throw new Error(' 数值太小了! ')
        }
        this.wheels = value;
    }
}

因为有增加性的属性名、方法名简写,当在CommonJS 模块定义中输出对象时,可以使用简洁写法:

module.exports = { getItem, setItem, clear }
// 等同于
module.exports = {
    getItem: getItem,
    setItem: setItem,
    clear: clear
}

 

内置类型

JS 中分为七种内置类型,七种内置类型又分为两大类型:基本类型和对象(Object)。

基本类型有六种: nullundefinedbooleannumberstringsymbol

其中 JS 的数字类型是浮点类型的,没有整型,都采用64位浮点类型存储。并且浮点类型基于 IEEE 754标准实现,在使用中会遇到某些 BugNaN 也属于 number 类型,并且 NaN 不等于自身,NaN是唯一一个不等于自身的JS常量

 

typeof

typeof 对于基本类型,除了 null 都可以显示正确的类型。

typeof 对于对象,除了函数都会显示 object。

对于 null 来说,虽然它是基本类型,但是 typeof null 会显示 object,这是一个存在很久了的 Bug。

如果我们想获得一个变量的正确类型,可以通过 Object.prototype.toString.call(xx)。这样我们就可以获得类似 [object Type] 的字符串。

 

整数字面量

JS整数共有四种字面量格式:十进制、二进制、八进制、十六进制。JS整数也属于浮点类型,JS没有整型。

对于非十进制,如果超出了数值范围,则会报错。

  • 八进制

八进制字面值的第一位必须是0,然后是八进制数字序列(0-7)。如果字面值中的数值超出了范围,那么前导0将被忽略,后面的数值被当作十进制数解析。例如:

var n8 = 012
console.log(n8) //10
var n8 = 09
console.log(n8) //9
  • 十六进制

十六进制字面值的前两位必须是0x,后跟十六进制数字序列(0-9,a-f),字母可大写可小写。如果十六进制中字面值中的数值超出范围则会报错。

var n16 = 0x11
console.log(n16) //17
var n17 = 0xw //Uncaught SyntaxError: Invalid or unexpected token
  • 二进制

二进制字面值的前两位必须是0b,如果出现除0、1以外的数字会报错。

var n2 = 0b101
console.log(n2) //5
var n3 = 0b3 //Uncaught SyntaxError: Invalid or unexpected token

 

JS浮点数并不精确,0.1+0.2 != 0.3

console.log(0.1+0.2 === 0.3) //false
console.log(0.3/0.1) //2.9999999999999996
console.log((0.3 - 0.2) === (0.2 - 0.1)) // false

为什么会不精确?

人类写的十进制小数,在计算机世界会转化为二进制小数。对于上面提到的 0.3 这个是进制小数,换算成二进制应该是什么呢?

0.01 = 1/4 = 0.25 //小
0.011 =1/4 + 1/8 = 0.375 //又大了
0.0101 = 1/4 + 1/16 = 0.334 //还大
0.01001 = 1/4 + 1/32 = 0.28125 //又小了
0.010011 = 1/4+ 1/32 + 1/64 = 0.296875 //接近了

根据国际标准IEEE754,JS的64位浮点数的二进制位是这样组成的:

1: 符号位,0正数,1负数
11: 指数位,用来确定范围
52: 尾数位,用来确定精度

后面的有效数字部分,最多有52个bit。这52个bit用完了,如果仍未准确,也只能这样了。在做小数比较时,比较的是最后面52位bit,它们相等才是相等。所以,0.1 + 0.2不等于0.3也不稀奇了,在数学上它们相等,在计算机它们不等。

 

字符串字面量

字符串字面量,并不完全等于字符串对象。它可以使用字符串对象的所有方法,但它无法创建并保持属性:

var a = "123"
console.log(a.length) //3
a.abc = 100
console.log(a.abc) //undefined

a = new String("123")
a.abc = 100
console.log(a.abc) //100

可以认为,使用字符串字面量创建的对象均是临时对象,当调用字符串字面量变量的方法或属性时,均是将其内容传给String()重新创建了一个新对象,所以调用方法可以,调用类似于方法的属性(例如length)也可以,但是使用动态属性不可以,因为在内存堆里已经不是同一个对象了。

想象这个场景可能是这样的:

程序员通过字面量创建了一个字符串对象,并把一个包裹交给了他,说:“拿好了,一会交给我”。字符串对象进CPU车间跑了一圈出来了,程序员一看包裹丢了,问:“刚才给你的包裹哪里去了?”。字符串对象纳闷:“你什么时候给我包裹了?我是第一次见到你。”

 

模版字符串字面量

在es6中,提供了一种模板字符串,使用反引号(`)定义,这也是一种字符串字面量。

使用模板字符串,原来需要转义的特殊字符例如单引号、双引号,都不需要转义了。反引号中的所有空格和缩进和换行都是有效字符。

标签模板字面量 过滤HTML字符串,防止用户输入恶意内容:

function filterSpitefulCode(strings,...values){
   return strings.reduce((s,v,idx)=>{
       if(idx>0){
           const prev=values[idx-1].replace(/</g,"&lt;")
           .replace(/>/g,"&gt;")
           s+=prev
       }
       return s+v
   },'')
}

const badCode= '<script>alert("abc")</script>'
const message=filterSpitefulCode`<p>${badCode} has been transformed safely~`

console.log(message)
// <p>&lt;script&gt;alert("abc")&lt;/script&gt; has been transformed safely~

 

 正则表达式字面量

var re = /[a-z]/gi   // 使用字面量创建
console.log("abc123XYZ".replace(re,"")) // 123

var re  = new RegExp("[a-z]", "gi")  //使用标准形式创建

常用的模式修饰符有:

g 全局匹配
m 多行匹配
i 忽略大小写匹配

在es5之前,使用字面量创建的正则,如果正则规则相同,则它们是同一个对象。这种bug在es5中已经得到修正。

 

数组字面量

数组字面量尾部逗号会忽略,但中间的不会

var myList = ['home',,'school',]
console.log(myList.length) // 3

var myList = ['home',,'school',,]
console.log(myList.length) // 4

 

函数字面量

 

布尔字面量

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值