js
1. ('b' + 'a' + +'a' + 'a').toLowerCase()
;('b' + 'a' + +'a' + 'a').toLowerCase() // 输出banana
// 关于 NaN
// 1. 任何 数字 和 NaN 计算都是 NaN
// 2. 任何数字和 undefined 运算,得到 NaN;
2. 计算转换问题
[]+{}//'[object Object]'
[]+[]//''
{}+[]//0 //+[] //[].toString() == ""; +" " == 0
只有以下两种形式
- number + number
- string+string
[ ]+{ } []会通过隐式转换规则,调用 toString 方法转换为 "" ,同理{}转换为[object Object], 相加得出字符串拼接结果 [object Object]
{} + [] js 解析器 会将{} 看作代码块,然后执行 +[] 得到 0
3. (!+[]+[]+![]).length//9
;(!+[] + [] + ![]).length //9
输出 9
- 第一步计算+[] 得到 0
- 第二步计算!+[]得到 true
- 第三步计算!+[] + [] 即 true+ [] = true+'' 得到字符串 'true'
- 第四步计算!+[] + [] + ![] = 'true'+'false' 得到 'truefalse'
- 最后得到 9
4. 变量提升, js 的预编译
//6.// 函数
function fn(a) {
console.log(a) //根据AO对象中的数据第一个打印的是:fn()
// 变量声明+变量赋值(只提升变量声明,不提升变量赋值)
var a = 123 // 执行到这时,由于变量赋值是不提升的,所以函数被123覆盖了
console.log(a) // 123
// 函数声明
function a() {} // 这里被提升上去了,可以忽略
console.log(a) // 123
// 函数表达式
var b = function () {}
console.log(b) // 根据AO对象中的数据:fn()
// 函数
function d() {}
}
//调用函数
fn(1)
5. 其他
0 == 0 //true
0 == [] //true
0 == [] //false
typeof NaN //number
99999999999//100000000000
0.1+0.2==0.3//false 精度丢失
Math.max()//-Infinity 负无穷
Math.min()//Infinity 正无穷
[] == false //true
0==false //true
undefined == false //true
NaN == false //true
== false //true 包括多空格
null == false //true
6.onload 和 ready
- onload()
执行时机:等待页面中的所有资源(包括图片、视频等资源)css js html 都加载完成后,才会执行。
而且在 js 中文件中只有一个 onload 事件。
- ready()
表示文档结构已经加载完成(不包含图片等非文字媒体文件)
执行时机:等待页面 Dom 树加载完成后,就开始执行。
在 js 文件中可以出现多个 ready(),并且按照顺序执行。
js 对象的 set 和 get 用法
对象的 set get 是 es5 的中对象的特性,使用示例:
- 在初始化对象的时候这样使用
var obj = {
a: 1,
b: 2,
set c(x) {
console.log('c 被赋值:', x)
c = x
},
get c() {
console.log('c 被取出: ', c)
return c
},
}
obj.c = 3 //c 被赋值: 3
obj.c //c 被取出: 3
- 对象初始化之后可以这样添加属性
var obj = {
a: 1,
b: 2,
}
obj.__defineGetter__('c', function () {
return c
})
obj.__defineSetter__('c', function (x) {
c = x
})
defineGetter 方法可以将一个函数绑定在当前对象的指定属性上,当那个属性的值被读取时,你所绑定的函数就会被调用。 该特性是非标准的,请尽量不要在生产环境中使用它!
- 使用 defineProperty
Object.defineProperty(obj, c, {
set: function (x) {
console.log('c 被赋值:', x)
c = x
},
get: function () {
console.log('c 被取出:', c)
return c
},
})
obj.c = 3 //c 被赋值: 3
obj.c //c 被取出: 3
对象的遍历
for..in..遍历
- 遍历自身及原型链上所有可枚举的属性
- 并不需要将原型链上的属性也遍历出来
- 还进行了原型链查找,当只需要遍历对象自身的时候,性能上会收到一定影响。
for (let n in qiu) {
// 判断是否实例自身拥有的属性
if (qiu.hasOwnProperty(n)) {
console.log(n)
}
}Object.keys 遍历
返回一个数组,包括对象自身的(不含继承的)所有可枚举属性
const searchObj = {
title: 'javascript',
author: 'Nicolas',
publishing: "O'RELLY",
language: 'cn',
}
let searchStr = Object.keys(searchObj)
.map((item) => `${item}=${searchObj[item]}`)
.join('&')
let url = `localhost:8080/api/test?${searchStr}`Object.getOwnPropertyNames 遍历
返回一个数组,包含对象自身(不含继承)的所有属性名
与 Object.keys 的区别在于 Object.getOwnPropertyNames 会把不可枚举的属性也返回。除此之外,与 Object.keys 的表现一致
var Person = function ({ name = 'none', age = 18, height = 170 } = {}) {
this.name = name
this.age = age
this.height = height
}
Person.prototype = {
type: 'Animal',
}
var qiu = new Person()
// 将height属性设置为 不可枚举
Object.defineProperty(qiu, 'height', {
enumerable: false,
})
var keys = Object.getOwnPropertyNames(qiu)
console.log(keys)
// output: ['name', 'age', 'height']说好的 for..of..,为什么无效
在 ES6 中新增了迭代器与 for..of..的循环语法,在数组遍历、Set、Map 的遍历上,十分方便。然而当我应用在对象(特指 Object 的实例 )上时(如下代码),浏览器给我抛了一个异常:Uncaught TypeError: searchObj is not iterable。
const searchObj = {
title: 'javascript',
author: 'Nicolas',
publishing: "O'RELLY",
language: 'cn',
}
for (let n of searchObj) {
console.log(n)
}
// Uncaught TypeError: searchObj is not iterable在 ES6 中,对象默认下并不是可迭代对象,表现为其没有[Symbol.iterator]属性,可以通过以下代码对比
const searchObj = {
title: 'javascript',
author: 'Nicolas',
}
const bookList = ['javascript', 'java', 'c++']
const nameSet = new Set(['Peter', 'Anna', 'Sue'])
console.log(searchObj[Symbol.iterator]) // undefined
console.log(bookList[Symbol.iterator]) // function values(){[native code]}
console.log(nameSet[Symbol.iterator]) // function values(){[native code]}
// 注,Set、Map、Array的[Symbol.iterator]都是其原型对象上的方法,而非实例上的,这点需要注意而 for..of..循环,实际上是依次将迭代器(或任何可迭代的对象,如生成器函数)的值赋予指定变量并进行循环的语法,当对象没有默认迭代器的时候,当然不可以进行循环,而通过给对象增加一个默认迭代器,即[Symbol.iterator]属性,就可以实现,如下代码:
Object.prototype[Symbol.iterator] = function* keys() {
for (let n of Object.keys(this)) {
// 此处使用Object.keys获取可枚举的所有属性
yield n
}
}
const searchObj = {
title: 'javascript',
author: 'Nicolas',
publishing: "O'RELLY",
language: 'cn',
}
for (let key of searchObj) {
console.log(key)
}
// output: title author publishing language
null 和 undefined
区别
- null 和 undefined 都代表没有;
- typeof null -->"object";空对象指针;
- null 表示现在没有,但是以后可能会有;undefined 表示现在没有,以后也没有;
常见的 null 的情况;
- 通过 ID 获取元素,如果 ID 名字不存在,那么返回 null;
- 通过正则进行捕获时,如果没有获取到内容,那个结果是 null;
- 在清空对象,销毁堆内存是,给对象赋值为 null
undefined 情况
- 当获取对象属性名对应的属性值时,如果属性名不存在,那么返回值是 undefined.
- 函数的形参如果没有实参赋值,在函数中默认存储 undefined
- 如果函数没有 return,那么函数的返回值是 undefined.
- 如果变量只声明,没有赋值,那么默认存储是 undefined.