1、reflow(回流)/repaint(重绘)
2、类型转换为Boolean类型
3、冒泡事件相关
4、void()
5、Javascript 全局函数
6、关于函数的 length 属性
7、数组中字符串键值的处理
8、给定一组 url 实现并发请求
9、类型转换问题
10、属性的遍历
11、数字转为千位制
1、reflow(回流)/ repaint(重绘)
会引起reflow:
1:改变窗口大小
2:改变文字大小
3:内容的改变,如用户在输入框中敲字
4:激活伪类,如:hover
5:操作class属性
6:脚本操纵DOM
7:计算offsetWidth 和 offsetHeight
8:设置style 属性
会引起repaint的:
如果只是改变某个元素的背景色、文字颜色、边框颜色等不影响他周围或内部布局的属性,只会引起浏览器的repaint
2、类型转换
1:基础类型
undefined:值未定义
boolean:布尔值
string:字符串
number:数值(整型和浮点)
object:对象或null
function:函数
2:任何对象转为布尔值,都会得到 true。而JS中,只有 0,-0,NaN,null,“”,undefined 这六个值转为布尔值时,结果为 false。
boolean 对象与 boolean 值得区别:
var x = nwe Boolean(false); // x = false
当一个值为false的boolean对象放到条件语句中时,Boolean 对象的值会被当作 true 来计算,但它本身的值并没有改变,依旧是 false。
实例:
var x = new Boolean(false);
if (x) {
alert('hi')
}
var y = Boolean(0)
if (y) {
alert('hello')
}
结果是:hi
3:计算
var test = '3000' - 0
typeof test === 'number' // true
console.log(test) // 3000
-
减法运算符会将字符串 ‘3000’ 调用Number()转换为3000再计算;
3、冒泡事件相关
常见不支持冒泡事件:
focus
blur
mouseenter
mouseleave
load
unload
resize
4、void()函数
JS中函数void()的运用大体是这种形式;
void() 是运算符,对任何值都返回 undefined;和 typeof 运算符号一样可以 void (0) = void 0;
void function main () {};申明此函数返回的是 undefined;没有 return 的函数默认也是返回 undefined;所以没有写的必要化
所以上面链接的形式也可是: javascript:void ''
, javascript:void "1"
, javascript:undefined
function(){}();
会运行错误, 如下可以正确被运行.
void function(){ alert(1) }()
5、Javascript全局函数
函数 | 描述 |
---|---|
decodeURI() | 解码某个编码的URI |
decodeURIComponent() | 解码一个编码的URI组件 |
encodeURI() | 把字符串编码为URI |
encodeURIComponent() | 把字符串编码为URI组件 |
escape() | 对字符串进行编码 |
eval() | 计算 Javascript 字符串,并把它作为脚本代码来执行 |
isFinite() | 检查某个值是否为无穷大的数 |
isNaN() | 检查某个值是否是数字 |
Number() | 把对象的值转为数字 |
parseFloat() | 解析一个字符串并返回一个浮点数 |
parseInt() | 解析一个字符串并返回一个整数 |
String() | 把对象的值转为字符串 |
unescape() | 对由 escape() 编码的字符串进行编码 |
6、关于函数的 length 属性
函数是有 length 属性的,函数的 length 将返回没有指定默认值的参数个数。
(() => 1).length === 0 // true
(a => a).length; // 1
(function (a) {}).length // 1
(function (a=5) {}).length // 0
(function (a, b, c = 5)).length // 2
该函数预期传入的参数个数。某个参数指定默认值以后,预期传入的参数个数就不包括这个参数了。
(function (...args){}).length // 0
如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。
(function (a=0, b, c){}).length // 0
(function (a, b = 0, c){}).length // 1
7、数组中字符串键值的处理
在 Javascript 中数组是通过数字进行索引,但是他们也是对象,所以也可以包含 字符串 键值和属性,但是这些不会被计算在数组的长度内。
如果字符串简直能够被强制转换为十进制数字的话,它也会被当做数字索引来处理。
const arr = []
arr[0] = 1
arr['1'] ='哈哈'
arr['crm'] = 'cryname'
console.log(arr) // [1, "哈哈", crm: "cryname"]
console.log(arr.length) // 2
ps: 数据类型:6 + 2
Number / String / Boolean / Undefined / Null / Object (包含:Array , function, data 等) / Symbol / bigInt(操作大整数)
NaN
是 number 的一种特殊数值, js 规定的NaN 不等于NaN
8、给定一组 url 实现并发请求
题目:给定一组url,利用js的异步实现并发请求,并按顺序输出结果。
Promise.all
const urls = ['./1.json', './2.json', './3.json']
function getData(url) {
// 返回一个 Promise 利用 Promise.all 接受
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.responseType = 'json'
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr.response)
}
}
}
xhr.open('GET', url, true)
xhr.send(null)
})
}
function getMultiData (urls) {
// Promise.all 接受一个包含 promise 的数组,如果不是 promise 数组会被转成 promise
Promise.all(urls.map(url => getData(url))).then(results => {
console.log(results)
})
}
不用Promise 实现,可以加个回调函数,等数据全部出来后,触发回调函数传入得到的数据,那么数据全部回来就是我们要考虑的核心,可以用数组或对象,然后判断一下数组的length 和传入的 url 长度是否一致做判断。
使用对象做映射
const urls = ['./1.json', './2.json', './3.json']
function getAllData (urls, callback) {
const result = {}
function getData (url, idx) {
const xhr = new XMLHttpRequest()
xhr.responseType = 'json'
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
result[idx] = xhr.response
// 如果两者 length 相等说明都请求完成了
if (Object.keys(result).length === urls.length) {
// 给对象添加 length 属性,方便转换数组
result.length = urls.length
callback && callback(Array.from(result))
}
}
}
}
xhr.open('GET', url, true)
xhr.send(null)
}
// 触发函数执行
urls.forEach((url, idx) => getData(url, idx))
}
// 使用
getAllData(urls, data => {
console.log(data)
})
使用数组实现
const urls = ['./1.json', './2.json', './3.json']
function getAllData (urls, callback) {
const results = []
let count = 0
function getData (url, idx) {
const xhr = new XMLHttpRequest()
xhr.responseType = 'json'
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
results.push(xhr.response)
if (++count === urls.length) {
callback && callback(results)
}
}
}
}
xhr.open('GET', url, true)
xhr.send(null)
}
// 触发函数执行
urls.forEach((url, idx) => getData(url, idx))
}
// 使用
getAllData(urls, data => {
console.log(data)
})
9、类型转换问题
原题:如何让 (a1 && a2 && a== 3) 的值为true?
== 类型转换的基础规则:
NaN
与任何值都不相等,包括它自己undefined
与null
相等(==),其他都不等- 对象与字符串类型转换作比较,会把对象转换成字符串然后做比较
- 其他类型比较都要转换成
数字
作比较
那么重写 toString 或者 valueOf 方法就可以了
const a = {
val: 1,
toString () {
return this.val++
}
}
if (a==1 && a==2 && a==3) {
console.log('ok')
}
利用 Object.defineProperty 中get新增全局参数
const i = 1;
Object.defineProperty(window, 'a', {
get () {
return i++
}
})
if (a == 1 && a == 2 && a == 3) {
console.log('ok')
}
拓展:
为什么 [] == ![] // true
- 首先
[].toString()
会得到一个‘’
字符串 ![]
得到一个布尔值false
//''
与false
作比较肯定要转换成数字比较- 那么
''
转换则为0
,false
转换也是0
,所以为true
10、属性的遍历
ES6 一共有5种方法可以遍历对象的属性。
可不可枚举查看对象描述属性中的 enumerable
介绍
(1)、for … in
for ... in
循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
(2)、Object.keys(obj)
Object.keys(obj)
返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
(3)、Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames(obj)
返回一个数组,包含对象自身的所有属性(不含Symbol 属性,但是包括不可枚举属性)的键名。
(4)、Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols(obj)
返回一个数组,包含对象自身的所有 Symbol 属性的键名。
(5)、Reflect.ownKeys(obj)
Reflect.ownKeys(obj)
返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。
- 首先遍历所有数值键,按照数值升序排列。
- 其次遍历所有字符串键,按照加入时间升序排列。
- 最后遍历所有 Symbol 键,按照加入时间升序排列。
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2' '10', 'b', 'a', Symbol()]
例:
function cat (name) {
this.name = name
}
cat.prototype.color = 'yellow'
var cat2 = new cat('小猫')
for(var key in cat2){
console.log(key)
}
// name color
Object.keys(cat2) // ['name']
Object.getOwnPropertyNames(cat2) // ['name']
Object.getOwnPropertySymbols(cat2) // []
Reflect.ownKeys(cat2) // ['name']
var obj = {b: 1, a: 1, 10: 1, 5: 1, [Symbol()]:1}
Object.defineProperty(obj, 'd', {
value: 1,
enumerable: false
})
Object.defineProperty(obj, 'c', {
value: 1
})
Object.keys(obj) // ["5", "10", "b", "a"]
Object.getOwnPropertyNames(obj) // ["5", "10", "b", "a", "d", "c"]
Object.getOwnPropertySymbols(obj) // [Symbol()]
Reflect.ownKeys(obj) // ["5", "10", "b", "a", "d", "c", Symbol()]
11、数字转为千位制
function setCount (count) {
return count.toString().replace(/(\d)(?=(\d{3})+$)/g, "$1,")
}