目录
1.类型转换练习
2.数据之间运算
算术运算
比较运算
逻辑运算
3.动态执行JS(类似eval方法)
1.eval()方法
2.setTimeout
3.创建DOM节点进行添加
4.Function的最后一个参数当作函数体直接运行
4.promise工具函数练习
5.统计字符频率写法的发散思维
6.深拷贝和浅拷贝
深拷贝的一些方法
手动递归赋值
JSON的序列化与反序列化
第三方的库(略)
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 = nulllet 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,0console.log('null/undefined->number', Number(null), Number(undefined));// 0,NaNconsole.log('str->number', Number('\n'), Number('123'), Number('123abc'));// 0,123,NaN// 所有转boolconsole.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 =2eval(code) }fun1('console.log("a",a)') // a 2 console.log('你好'); // 2 ,你号
2.setTimeout
异步,全局作用域
var a =1 const fun1 = (code)=>{var a =2setTimeout(code) }fun1('console.log("a",a)') // a 1 console.log('你好'); // 你好,a 1
3.创建DOM节点进行添加
同步方法,全局作用域,弊端产生一个元素
var a =1 const fun1 = (code)=>{var a =2const script = document.createElement('script')script.innerHTML = codedocument.head.appendChild(script) }fun1('console.log("a",a)') // a 1 console.log('你好'); // a 1 你好
4.Function的最后一个参数当作函数体直接运行
同步方法,全局作用域
var a =1 const fun1 = (code)=>{var a =2new 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 方法,则认为它类似于 Promisereturn 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));
第三方的库(略)