js解析引擎相关笔试题的相关代码

console.log(2>3); //flase
console.log(3<2<1); //true
console.log(1>2>3); //flase
console.log( [1<2<3,3<2<1] ); //[true, true]
console.log(true==1);    //true
console.log(true=="1");  //true,因为true是1,所以“1”会转成1
console.log(true===1); //false  boolean和number数据类型不同
console.log(typeof true); //boolean
首先,我们需要知道,在编程语言中 0 == false1 == true(是01不是“0”,“1”)是正确的。
因此在分析3<2<1时,我们可以将其分为两步,首先是3<2返回是flase,也就等价于0。
所以0<1结果自然是true了。
(01其实是计算机二进制,输出成true,flase,然后两个number类型比较大小就是比较对应的二进制值,而js的字符串在进行比较时,会根据ASCII码值比较,但ASCII码值也是由二进制转换成十进制得到的)
let a=[1]
let b=[1]
console.log(a==b); //flase   
console.log([]==[]); //false 相当于分别创建了两个引用数据类型的变量,指向不同的堆内存地址
因为数组、对象都是引用数据类型,a和b只是两个指针存储在栈中,实则比较的是堆内存地址
console.log(a===b); //flase
let a=[1,2]
let b=a
console.log(b==a); //true  //直接赋值,堆内存地址相同
console.log(b===a); //true

那两个数组如何比较值是否相等?

let a=[1,2,3]
let b=[1,2,3]
console.log(a.toString(),b.toString(),a.toString()===b.toString())
console.log(JSON.stringify(a),JSON.stringify(b),JSON.stringify(a)===JSON.stringify(b))
但是依旧会存留问题
1.数组顺序不一致,(可以使用.srot()做一下排序)
2.由于转义成了字符串,会导致原本是数字的数据,会变成字符串类型,可能会影响对比的准确性
console.log(2==[2]); //true  
console.log(2==[[2]]); //true 因为左面的2是基本数据类型,所以js解析时候就做了件事 [[2]].toString(),然后就是“2”
console.log(2==[[[2]]]); //true
console.log(2===[[[2]]]); //false

 console.log([true]=="true"); //true  js解析时候用了toString转换,所以值相同,但类型不同,且js是弱类型语言
 console.log([true]==="true"); //false
 
 console.log([true]==true); //false 字符串“true”和true比较,值相当于true字符和1
  console.log([true]===true); //false

let arr=[5,2,4]
console.log(arr.toString()); //5,2,4

console.log([]==false); //true   [].tostring()结果是空,也就是flase
console.log([]==0);//true 
console.log([]=="0"); //false 因为他已经弱类型转换一次成了flase,不能再转换一次成字符0
console.log(false=="0"); //true
console.log(3.toString()); //报错
console.log((3).toString()); //“3”  有括号就不会报错,或者就是下面的定义一个变量
var c=8;  console.log(c.toString()); //"8" 
console.log(3..toString()); //“3”
 console.log(3...toString()); //报错
 console.log(.3);// 0.3
  console.log(3.); //3
 console.log(+5); //5
console.log(-5); //-5
 console.log(.3.toString()); //“0.3”
 console.log(.3..toString()); //报错
 
运算符优先级的问题,点运算符会被优先识别为数字常量的一部分,然后才是对象属性访问符
在 JS 中,3.13..3 都是合法的数字
3.toString() 会被 JS 引擎解析成 (3.)toString() 报错
3..toString() 会被 JS 引擎解析成 (3.).toString() "3"
3...toString() 会被 JS 引擎解析成 (3.)..toString() 报错
.3.toString()会被 JS 引擎解析成(.3.toString()0.3.3..toString()会被 JS 引擎解析成(.3..toString() 报错
1. (function(){
            var x=y=1
        })()
        console.log(y); //1
        console.log(x); //x is not defined
        
2. (function(){
            var x=1,y=1 //逗号代表这条语句还未结束
        })()
     
        console.log(y); //y is not defined
        console.log(x); //x is not defined        
这道题目涉及到变量提升的范围,以及赋值语法。
var x=y=1 等价于 var x=y; y=1; 这里的y会被提升至全局域,所以是上述答案。
var x=1,y=1 等价于var x=1; var y=1, 这样写的话,x,y都是局部变量,不会被提升。


函数的函数声明有一个重要特征 —— 函数声明提升 
1.
 keqing();   //Hi~
function keqing(){   
  alert('Hi~');
}

函数:在读取执行代码之前会先读取函数声明

2.
keqing();  // Uncaught TypeError: keqing is not a function  
console.log(keqing); //undefined 
var keqing = function(){ //
  alert('Hi~');
}
console.log(keqing); //f(){}
函数表达式:没有函数声明提升,在执行前必须先赋值,相当于只是变量提升,还要赋值后才可以用,但值不会提升

3.
console.log(a);  //undefined  变量只是声明提升,但还没赋值,值不会提升
var a=5
console.log(a); //5

1.        for(var i=0;i<2;i++)  //这个地方i++与++i都没关系,因为没直接参与运算
{ 
    setTimeout(() => {
        console.log(i++); //2 3  相当于先打印再加,打印即参与运算
        console.log(i); //3 4
    }, 1000);
}

 2.       for(var i=0;i<2;i++)
{ 
    setTimeout(() => {
        console.log(++i); //3 4  当于先加再打印
        console.log(i); //3 4
    }, 1000);
}

3.
        for(let i=0;i<2;i++)
{ 
    setTimeout(() => {
        console.log(++i); //1 2
        console.log(i); //1 2
    }, 1000);
}
        var a=[1,2,3]
        var b=[1,2,3]
        var c=[1,2,4]
        var d=a
        
        console.log(a.toString()); //1,2,3
        console.log(d==a); //true 堆中相同内存地址
        console.log(d===a); //true 堆中相同内存地址
        console.log(a==b); //flase  堆中不同内存地址
        console.log(a===b); //false   堆中不同内存地址
       console.log(a>c); //false 相当于两边[1,2,3].toString()转化为字符串,再先比较第一个值的ASCALL码值,相同再比较第二个,以此类推
       console.log(a<c); //true 
var a = {}, b = Object.prototype;
[a.prototype === b, Object.getPrototypeOf(a) === b]
结果为[false,true]
首先prototype属性是函数才有的属性,对象是没有的,对象要想访问原型对象需要用object.__proto__,
因此a.prototype返回undefined,因为a是一个对象,它没有prototype属性。
Object.getPrototypeOf(a)相当于a.__proto__,所有用Object()创建的对象它们的原型对象都指向同
一个对象(包括字面量形式创建的对象),因此Object.getPrototypeOf(a) === b返回true.
setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three

需要注意的是,立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时执行执行,不是马上执行,也不是在下一轮“事件循环”的开始时执行
原因:传递到 then() 中的函数被置入了一个微任务队列,而不是立即执行,这意味着它是在 JavaScript 事件队列的所有运行时结束了,事件队列被清空之后,才开始执行
所以定时器是最后被调起,最后执行
        Promise.resolve().then(() => console.log(2)).
        then(() => console.log(3)).
        catch(() => console.log(4));
        console.log(1);  
        // 1, 2, 3 先执行1再执行resolve的Promise对象的回调函数
Promise.resolve(8).then((res) => console.log(res)).
        then((res) => console.log(res)).
        catch(() => console.log(4));
        console.log(1);  
        // 1, 8, undefined 先执行1再执行resolve的Promise对象的回调函数,第一个then接收完回调函数参数res后,第二个then接收不到了
Promise.reject().then(() => console.log(2)).
then(() => console.log(3)).
catch(() => console.log(4));
console.log(1); // 1, 4  先执行1再执行reject的Promise对象的回调函数

resolve()本质作用:(reject同理)
resolve()是用来表示promise的状态为fullfilled,相当于只是定义了一个有状态的Promise对象,但是并没有调用它;
promise调用then的前提是promise的状态为fullfilled;
只有promise调用then的时候,then里面的函数才会被推入微任务中

console.log([,,,,,]); //[empty × 5],就是5个undefined
console.log([,,,,,].length); //5
console.log([,,,,,].join(",")); //,,,, 五个元素,则连接只需要四个字符并且每个元素都是空的
let c={d:5}
let d={d:5}
let e=c
console.log(e===c); //true 对象(引用数据类型)指向相同的内存地址
console.log(c===d); //false 对象(引用数据类型)指向不同的内存地址
var a = 111111111111111110000,
    b = 1111;
   a + b;

是一道考查JavaScript数值的题,由于JavaScript实际上只有一种数字形式IEEE 754标准的64位双精度浮点数,其所能
表示的整数范围为-2^53~2^53(包括边界值)。这里的111111111111111110000已经超过了2^53次方,所以会发生精度丢失的情况。

这个又一次考察JavaScript中的最大值问题,JavaScript中最大值是Math.pow(2, 53)=9007199254740992,计算
过程中如果超出这个最大值范围就不准确了,但是怎么个不准确法,是不确定的。这里输出111111111111111110000, 还是a的值。
var two   = 0.2;
var one   = 0.1;
var eight = 0.8;
var six   = 0.6;
console.log([two-one === one, eight - six === two]) //[true, false]
console.log( eight-six); //0.20000000000000007
console.log(two-one); //0.1
console.log(0.1+0.2); //0.30000000000000004
console.log(0.8+0.6); //1.4
console.log(0.2-0.1); //0.1

这个考察的是JavaScript数字精度问题,JavaScript的Number类型为双精度IEEE 754 64位浮点类型,这个问题造成0.1 + 0.2= 0.30.8 - 0.6= 0.2等等。
遇到IEEE 754标准中的浮点数并不能精确地表达小数时,可以使用toFixed方法转换下,toFixed方法可以规定保留几位小数点

  ( eight - six ).toFixed(1) == two  //true  toFixed方法可以规定保留几位小数点
  ( eight - six ).toFixed(1) === two  //false  转换后的类型不同
  console.log( typeof (eight-six)); //number
  console.log(typeof  (eight-six).toFixed(1) ); //string

function foo(){}

var old=foo.name
console.log(old); //foo

foo.name="bar" //不会改变函数的名字

console.log(foo.name); //foo

在Javascript规范中提到,要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,并且规定null 和 undefined 是相等的。

console.log(undefined == null);   //true  
console.log(undefined==false); //false
console.log(null==false); //false
有文章对此进行了解释,大致是下面的意思:undefined的布尔值是falsenull的布尔值也是false,所以它们在比较时都转化为了false,所以 undefined == null 。但这种解释是错误的。

在Javascript规范中提到,要比较相等性之前,不能将 nullundefined 转换成其他任何值,并且规定nullundefined 是相等的。

console.log('' == 0 == false);    //false  js是弱类型语言,可以随意转换
function dy() {
   this.get=function(){
       console.log(1);
   }
}

dy.gets=function(){console.log(2);}  //只相当于dy这个函数对象的一个方法
dy.a=88 //只相当于dy这个函数对象的一个变量
dy.gets() //2 只有通过这种方法才可以调用
console.log(dy.a); //88
 

dy.prototype.get=function(){console.log(3);}


let newdy=new dy() 
newdy.get() //1   实例中要是没有get方法才会去该实例的原型中找
console.log(newdy.a); //undefined
newdy.gets() //newdy.gets is not a function

var a=1
var b=8;
var A={v:2};  //加个;隔开  不加分号跟下面的自执行函数混在一起会报错

(function(a,A){
console.log(a); //1
console.log(A); //{v: 2}
A.v=5
a=A.v
b=9  //全局的b

console.log(a); //5 形参a的值
})(a,A)

console.log(A.v); //5 引用数据类型占用一块相同的内存空间,所以可以通过形参改变值
console.log(a); //1 而基本数据类型,会任意开辟内存空间,所以形参重新开辟了内存空间,不会影响到全局的值

console.log(b); //9

//自执行函数不传参
for (var i= 0; i < 3; i++) {
  
(function(i){
   console.log(i); //3个undefined 形参永远要接收实参传进来的值
    setTimeout(() => {
        console.log(i); //3个undefined 形参永远要接收实参传进来的值
    }, 1000);
})()
    
}


//自执行函数传参,且用var声明i
for (var i= 0; i < 3; i++) {
  
(function(i){
   console.log(i); //0 1 2  实参传进来的值
    setTimeout(() => {
        console.log(i); //0 1 2 因为这个定时器存取了每次形参i的值,不是全局的i
        //在函数内部执行时,形参就默认是局部变量,所以会先在局部找,找不到再向全局中找(由内到外)
    }, 1000);
})(i)
    
}

//自执行函数传参,且用let声明i ,结果一样
for (let i= 0; i < 3; i++) {
  
(function(i){
   console.log(i); //0 1 2  实参传进来的值
    setTimeout(() => {
        console.log(i); //0 1 2 因为这个定时器存取了每次形参i的值,不是全局的i
    }, 1000);
})(i)
    
}
console.log(-9%2); //-1
console.dir(-10%2); //-0
console.log(-10%2===0); //true
console.log(Infinity%2); //NaN
var val = 'smtg';
console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing'); //Something
第一感觉输出Value is Something,但运行后发现输出Something,就是一个优先级的问题,上述代码等价于
console.log(('Value is ' + (val === 'smtg')) ? 'Something' : 'Nothing'),
//('Value is ' + (val === 'smtg'))结果为Value is true,所以最后输出Something

console.log('Value is ' + val === 'smtg')// flase
console.log('Value is ' + (val === 'smtg'))//Value is true
解析时js代码从前向后解析
   var name="Wordld";
  
    function name2(){
      console.log(name); //undefined  因为后面又声明了var name="jack",这会导致name变量提升到前面,会先从局部作用域中找name变量,但赋值没提升,所以就undefined

        if(typeof name==="undefined") //true
        {
            
            var name="jack"
            console.log("hellp"+name);  //hellpjack
        }
        else
        {
            console.log("hellp"+name);
        }

    }
   name2()
  function isOdd(num) {
       return num%2==1
   }
   function isEven(num) {
       return num%2==0
   }

   function isSane(num)
   {
       return isOdd(num)||isEven(num)
   }
   let arr=[8,16,-9,Infinity]
  let newarr= arr.map(isSane)
   console.log(newarr);  //[true, true, false, false]

//这就是js是弱类型语言的弊端,可以随意转换,而不需要强制转换
 var a=[0]
 if ([0]) {  //数组在这里表示有值所以就是true
     console.log(a==true); //[0].toString() 是0,所以是false
     console.log([0]==false); // true
 }else
 {
     console.log("Xxx");
 }


//
if ([]) {  //数组在这里表示有值所以就是true
    console.log(5); //5
}

//
    
 var a
 if (a) {   //a无值,则为false
     console.log(555);  //不执行 
 }
 

//
 if ("0") {   
     console.log(555); //555
 }else
 {
     console.log("Xxx");
 }


//
 
 if (0) {   
     console.log(555); 
 }else
 {
     console.log("Xxx");//Xxx
 }

var arr=new Array(3)
arr[0]=2
let newarr=arr.map(function(item){return "1"})
console.log(arr); // [2, empty × 2]  map函数不改变原数组
console.log(newarr); //['1', empty × 2]  只遍历映射有值的索引对应的元素
function sid(arr) {
    arr[0]=arr[2] //
}

function bar(a,b,c) {
    console.log(arguments); //[1,1,1]  arguments参数数组是引用数据类型,占用同一内存地址
    c=10;  //对参数的重新赋值,生效
    console.log(arguments); //[1,1,10]
    sid(arguments)
    console.log(arguments); //[10,1,10]
    return a+b+c

}
console.log(bar(1,1,1)) //21
var a=/123/
b=/123/;
console.log(a==b); //false   正则(RegExp)和日期(Date)是两个特殊的对象类型即引用数据类型
console.log(a===b); //false  两个变量指向不同的堆内存地址
function name() {
    temp=0
}
name()
console.log(temp); //0


//
function name() {
    temp=0
}
console.log(temp); //temp is not defined     name只是函数声明提升,但要被调用才会执行函数里面的内容
var name="张三"

function fun(a)
{      
a="李四"  
}
fun(name)

console.log(name); //张三  因为name是基本数据类型,在函数中执行重新开辟了内存空间储存参数a的值,不会影响name的值

//
var obj={
    name:"张三"
}
function fun(a)
{   
    a.name="李四" 
}
fun(obj)
console.log(obj.name); //李四  因为obj是引用数据类型,在函数中执行时操作的是同一堆内存空间,不会随意开辟新的内存空间

 <div id="app">
  
     <button @click="add">添加</button> 
   <span ref="test">{{msg}}</span>
   
    </div>
    <script>
const app = Vue.createApp({
    data() {
        return {
            
            msg:"ss"
        }
    },
    methods: {
        add(){
         this.msg="dd"
         //nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。你可以传递一个回调函数作为参数,或者 async await 返回的 Promise再继续执行。
         this.$nextTick(function(){ 
            console.log( this.$refs.test.innerHTML); //dd xuranr
            //不用nextTick而直接打印,结果会是ss,因为那时候数据虽然更新,但DOM还没更新完成
         })

                }
    },
})
app.mount("#app")
    function Person(first,last)
    {
        this.first=first;
        this.last=last;
        return 55
    }

    const ly=new Person("ss","cxc")
    const sa=Person("sa","ss")
    console.log(ly); //Person {first: 'ss', last: 'cxc'}
    console.log(sa); //55 没return返回值得话就是undefined
var a=[2,,3]
console.log(JSON.stringify(a)); //[2,null,3]   JSON.stringify()将JS对象转换为JSON格式的字符串
console.log(typeof JSON.stringify(a));  //string
console.log(a.toString()); //2,,3
  console.log(`${(x=>x)('I LOVE')} to program`); //I LOVE to program
  console.log(`${(x=>x)('I')}`); //I 相当于自执行函数传入参数I,然后返回I
//ES6解构赋值
let [a,b,c,d,e]="her"
console.log(e); //undefined
console.log(c);//r
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值