js之数据类型等面试题(二)

tech2025-10-15  2

考察push方法的运行 <script> Array.prototype.push=function push(value){ //1.把value放到末尾 this[this.length]=value; //2.长度累加 this.length++; }; let arr=[10,20]; arr.push(30); //================================== let obj={ 2:3, 3:4, length:2, push:Array.prototype.push } obj.push(1); // obj[2]=1; length:3 obj.push(2); // obj[3]=2; length:4 console.log(obj); //则obj变为如下: obj={ 2:1, 3:2, length:4, push:Array.prototype.push } </script> 数据类型转换 //比较的时候,两边类型不一样,会默认转为一样的,然后再进行比较(隐式转换) //对象字符串:把对象转换为字符串 //null==undefined null/undefined和其他任何值都不相等 //剩下的情况都是转换为数字 //----------- //对象转换为数字,浏览器底层处理如下: // +首先调取对象中[Symbol.toPrimitive]的这个属性(属性值是函数):获取原始值,如果这个函数不存在 // +继续调用对象的valueOf方法,如果也不存在,或者获取的结果并不是原始值(基本类型值) // +则继续调用对象的toString方法,先转换为字符串,再把字符串转换为数字。 let obj={}; console.log(obj[Symbol.toPrimitive]); //undefined let n=10; //字面量方式创建值:基本类型值/原始类型/值类型 let n=new Number(10); //构造函数方式创建值:引用数据类型 console.log(n.valueof()); //10 //基本数据类型值所属类的原型上都有valueof方法,获取其原始值 //Object.prototype.valueOf:此方法获取的结果是引用类型值(不算原始值,原始值一般指的是基本类型值) //Object.prototype.valueOf.call(10) //得到的结果是new Number(10) //数组/正则/函数所属类的原型上都没有valueOf,调用的都是Object.prototype.valueOf //Date.prototype.valueOf:获取日期对象的原始值(距离1970-1-1 00:00:00之间的毫秒差) console.log(new Date()-10); //1599051256501 console.log(({})-10); //NaN console.log(new Number(10)+10); //20 例题:a的值为什么,才会 输出ok // 方案一:利用数据类型转换的机制,我们重写方法实现效果 var a={ value=0, //valueof/toString [Symbol.toPrimitive](hint){ //浏览器调取这个方法的时候会传递一个hint:存储当前对象即将转换为什么值 //default:可能转换为数字或者字符串,例如:==比较或者加号运算 //number:一定转换为数字的,例如:减乘除等数学运算中 //string:一定是转换为字符串的,例如:字符串拼接 return ++this.value; } } //隐式调用:a[Symbol.toPrimitive] if(a==1&&a==2&&a==3){ console.log('OK'); } //方案二 let a=[1,2,3]; a.toString=a.shift; if(a==1&&a==2&&a==3){ console.log('OK'); } //方案三:利用数据劫持 Object.defineProperty / Proxy //如果a不是全局变量,则再看是否为window 的一个属性... let i=0; Object.defineProperty(window,'a',{ get(){ //获取window.a的属性,触发GETTER函数 return ++i; }, set(){ //window.a=xxx 触发SETTER函数 } }); if(a==1&&a==2&&a==3){ console.log('OK'); } 写toArray函数实现数组的输出 <script> let utils=(function (){ // toArray:转换为数组的方法 // @params // 不固定数量,不固定类型 // @return // [Array] 返回的处理后的新数组 //第一种 // function toArray(...args){ // //ES6剩余运算符接收到的实参本身就放到了数组中 // return args; // } //第二种 // function toArray(){ // //arguments获取到的是类数组,需要把他转换为数组 // //return Array.from(arguments); //ES2015 // //return [...arguments]; //es6中的展开运算符 // } //第三种 function toArray(){ let arr=[]; for(let i=0;i<arguments.length;i++){ arr.push(arguments[i]); } return arr; //直接改写成如下: //JS中的“鸭子”类型:arguments本身不是数组,但是结构和数组类似(超级类似:数字索引、逐级递增 、length存储集合长度...) return [].slice.call(arguments); } return { toArray }; })(); let ary=utils.toArray(10,20,30); console.log(ary); ary=utils.toArray('A',10,20,30); console.log(ary); </script>

slice

<script> //重写内置的slice,实现浅克隆的效果 function slice(){ //this->ary let arr=[]; for(let i=0;i<this.length;i++){ arr.push[this[i]]; } return arr; } let ary=[10,20,30]; console.log(ary.slice()); //slice()或者slice(0)都是实现数组的浅克隆 </script> 类数组(arguments/NodeList/HTMLCollection/JQ集合…) <script> let obj={ 0:10, 1:20, 2:30, length:3 }; //数组中的其他方法一样可以被借用 Array.prototype.forEach.call(obj,(item,index)=>{ console.log(item,index); }); //直接写成如下也可以 console.log(Array.from(obj)); </script>
最新回复(0)