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

  1. 考察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>
  1. 数据类型转换
    //比较的时候,两边类型不一样,会默认转为一样的,然后再进行比较(隐式转换)
    //对象
    字符串:把对象转换为字符串
    //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');
        }

  1. 写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>
  1. 类数组(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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值