目录
1.类型转换练习
对象转原始类型
1.先调用对象的valueOf方法,如果返回原始类型,则直接返回
2.如果valueOf返回的不是原始类型,则调用toString方法,如果返回原始类型,则直接返回
3.如果toString返回的不是原始类型,则报错
原始转字符串
例子:
String(null)
:'null'
String(undefined)
:'undefined'
String(123)
:'123'
String(true)
:'true'
String(true)
:'false'
原始转数字
Number(true)
:1
Number(false)
:0
Number(null)
:0
Number(undefined)
:NaN
Number('\n')
:0
Number('123')
:123
Number('123abc')
:NaN
所有转Boolean
记住为false的
Boolean(null)
:false
Boolean(undefined)
:false
Boolean(0)
:false
Boolean('')
:false
Boolean(NaN)
:false
// 定义所有的JS类型 let str = 'asdf' let num = 123 let bool = true let und = undefined let nul = null let obj = {} let arr = [] //JS类型转换规则 // 对象转原始类型 // 1.先调用对象的valueOf方法,如果返回原始类型,则直接返回 // 2.如果valueOf返回的不是原始类型,则调用toString方法,如果返回原始类型,则直接返回 // 3.如果toString返回的不是原始类型,则报错 // 原始转对象,不修改方法 const fun0 = () => { console.log(obj.valueOf(), obj.toString()) // [object Object],'[object Object]'; console.log('obj->str', String(obj), String(obj.valueOf()), String(obj.toString())) // '[object Object]', '[object Object]', '[object Object]' console.log('obj->number', Number(obj), Number(obj.valueOf()), Number(obj.toString())) // NaN,NaN,NaN } // 原始转对象,修改 valueOf 方法 const fun1 = () => { obj = { valueOf: function () { return 1 } } console.log('obj->number', Number(obj), Number(obj.valueOf()), Number(obj.toString())) // 1,1,NaN } // 原始转对象,修改 valueOf 和 toString 方法 const fun2 = () => { obj = { valueOf: function () { return {} }, toString: function () { return 1 } } console.log('obj->number', Number(obj), Number(obj.valueOf()), Number(obj.toString())) // 1,NaN,1 } // 原始转对象,修改 valueOf 和 toString 方法 const fun3 = () => { obj = { valueOf: function () { return {} }, toString: function () { return {} } } console.log('obj->number', Number(obj), Number(obj.valueOf()), Number(obj.toString())) // 报错 } fun1() fun2() fun3() // 其他的转换 const other_change = () => { // 原始转字符串 console.log(String(null), String(undefined), String(123), String(true)); // 'null','undefined','123',true // 原始转数字 console.log('bool->number', Number(true), Number(false)) // 1,0 console.log('null/undefined->number', Number(null), Number(undefined));// 0,NaN console.log('str->number', Number('\n'), Number('123'), Number('123abc'));// 0,123,NaN // 所有转bool console.log(Boolean(null), Boolean(undefined), Boolean(0), Boolean(''), Boolean(NaN)) // false,false,false,false,false } // other_change()
2.数据之间运算
算术运算
+,-, *, /, %, ++, --
规则:必须是原始数据类型
1.转换为数字然后运算
2.x+y其中一方是字符串,则都转换为字符串然后拼接
3.NaN和任何类型算术运算都得到NaN
比较运算
1.>,<,>=,<=,双方转原始
1.1转数字比较
1.2都是字符串,比较字典顺序
1.3两边存在NaN为false
2.===
2.1.类型和值必须相同
2.2两端存在NaN一定返回false
3.==
3.1两端类型相同比较值
3.2都是原始类型 转换成数字比较
3.3原始和对象,对象转原始,再都转数字
3.4undefined和null只有相互比较或是自身比较才返回 true
4.5两端存在NaN一定返回false
4.!= !== 相等取反
逻辑运算
!,&&, ||, ?:
转换为Boolean,然后比较
3.动态执行JS(类似eval方法)
1.eval()方法
同步执行,打印当前作用域
var a =1 const fun1 = (code)=>{ var a =2 eval(code) } fun1('console.log("a",a)') // a 2 console.log('你好'); // 2 ,你号
2.setTimeout
异步,全局作用域
var a =1 const fun1 = (code)=>{ var a =2 setTimeout(code) } fun1('console.log("a",a)') // a 1 console.log('你好'); // 你好,a 1
3.创建DOM节点进行添加
同步方法,全局作用域,弊端产生一个元素
var a =1 const fun1 = (code)=>{ var a =2 const script = document.createElement('script') script.innerHTML = code document.head.appendChild(script) } fun1('console.log("a",a)') // a 1 console.log('你好'); // a 1 你好
4.Function的最后一个参数当作函数体直接运行
同步方法,全局作用域
var a =1 const fun1 = (code)=>{ var a =2 new Function(code)() } fun1('console.log("a",a)') // a 1 console.log('你好'); // a 1 你好
4.promise工具函数练习
promise的标准有PromiseA+和官方ES Promise
"thenable" 对象是指具有
then
方法的对象。一个符合规范的
then
方法需要遵循以下要求:
- 它是一个函数,接受两个参数:
onFulfilled
和onRejected
,都是可选的回调函数。- 当 Promise 状态变为 fulfilled 时,
then
方法应该调用onFulfilled
回调函数。- 当 Promise 状态变为 rejected 时,
then
方法应该调用onRejected
回调函数。then
方法应该返回一个新的 Promise 对象。// 定义 Promise.prototype.catch 方法,用于捕获 Promise 链中的错误 Promise.prototype.catch = function (onRejected) { // 返回一个新的 Promise 对象,通过调用 then 方法,指定 onRejected 回调函数 return this.then(undefined, onRejected) } // 定义一个函数,用于判断一个对象是否类似于 Promise const isPromiseLike = function (obj) { // 如果对象存在且具有 then 方法,则认为它类似于 Promise return obj && typeof obj.then === 'function' } // 定义 Promise.prototype.resolve 方法,用于创建一个已解决的 Promise 对象 Promise.prototype.resolve = function (value) { // 如果 value 已经是 Promise 对象,则直接返回 if (value instanceof Promise) return value // 如果 value 类似于 Promise 对象,则返回一个新的 Promise 对象,并使用 value 的 then 方法 if (isPromiseLike(value)) { return new Promise((resolve, reject) => { value.then(resolve, reject) }) } // 如果 value 是普通值,则返回一个已解决的 Promise 对象 return new Promise(resolve => resolve(value)) } // 定义 Promise.prototype.reject 方法,用于创建一个已拒绝的 Promise 对象 Promise.prototype.reject = function (reason) { // 返回一个新的 Promise 对象,立即执行 reject 函数,将 reason 作为拒绝的原因 return new Promise((resolve, reject) => { reject(reason) }) }
5.统计字符频率写法的发散思维
简单类型的题目
一般写法
let str = 'qqwweqrqrqrqrqrqrqrsdvavsbbsavfGHSHJJMFJ' const my_sort = (str)=>{ str = str.split('') str = str.sort((a,b)=>a>b ? 1: a===b ? 0 : -1) return str } const fun1 = (str) => { let res = {} str = my_sort(str) for (let i = 0; i < str.length; i++) { if (res[str[i]]) { res[str[i]]++ } else { res[str[i]] = 1 } } return res } console.log(fun1(str))
独特写法
let str = 'qqwweqrqrqrqrqrqrqrsdvavsbbsavfGHSHJJMFJ' const my_sort = (str)=>{ str = str.split('') str = str.sort((a,b)=>a>b ? 1: a===b ? 0 : -1) return str } const fun2 = (str)=>{ str = my_sort(str) let res = [...str].reduce((r,cur)=> (r[cur]++ || (r[cur] = 1),r),{}) return res } console.log(fun2(str))
6.深拷贝和浅拷贝
知识点:
1.基本数据类型的赋值属于深拷贝,数据内容直接存放在栈中,赋值时直接是数据内容的给予
2.引用数据类型一般方法都属于浅拷贝
赋值时,新的对象获取到的是原对象存放在栈中的是一个指针,真实的数据内容是储存在堆中,栈中的指针指向队中的数据对应的地址。
所以修改新对象的值时,其实修改的是他们公共的堆内存的数据
所以为了一些不必要的错误,我们可以通过
创建一个新的对象,遍历需要克隆的对象,将需要克隆对象的属性依次添加到新对象上,返回新对象。这种方式进行引用数据类型的深拷贝。
深拷贝的一些方法
手动递归赋值
function deepCopy(obj) { if (obj === null || typeof obj !== 'object') { return obj; } const newObj = Array.isArray(obj) ? [] : {}; for (let key in obj) { newObj[key] = deepCopy(obj[key]); } return newObj; }
JSON的序列化与反序列化
let originalObject = { a: 1, b: { c: 2 } }; let deepCopyObject = JSON.parse(JSON.stringify(originalObject));
第三方的库(略)