实力脱坑题

423 阅读3分钟

题目1

当原型对象的属性值为基本类型的数据值时,通过实例对象修改属性值从而引起原型对象的属性值发生变化的情况不会发生。当原型对象的属性值为引用类型的数据值时,通过实例对象修改属性值就可能引起原型对象的属性值发生变化。

var fun = function(){}

fun.prototype = {
    info : {
    name : 'peter',
    age : 25
    }
}

var a = new fun();
var b = new fun();

a.info.name = 'jack';
b.info.name = 'tom';

打印输出a.info.name 和 b.info.name 会得到同一个值 tom
原因:
当原型对象的属性值为基本类型的数据时,更改实例不会引发原型对象的属性值的更改
但是, 当你原型对象的属性值为引用类型的数据时,更改实例也会引发原型对象属性值的变化。

var fun = function(){
    this.name = 'peter';
    return {
    name: 'jack'
    };
}

var p = new fun();

打印p.name 输出 jack而不是peter

var fun = function(){
    this.name = 'peter';

    return 'jack';    
 }

var p = new fun();

打印p.name输出peter

原因: 以上两个例子都是return类的实例化, 这种方式遵循一个原则: 如果这个函数是构造函数,则默认返回this对象,如果构造函数内使用了return语句,并且return后跟的是一个对象,则这个构造函数返回的是这个对象,否则返回this

var fun = function(){
    this.info = {
    name : 'peter',
    age : 25
    }
}

fun.prototype = {
    info : {
    name : 'peter',
    age : 25
    }
}

var a = new fun();
var b = new fun();

a.info.name = 'jack';
b.info.name = 'tom';

打印a.info.name 输出 jack,打印b.info,name输出 tom

原因: 
原型模式执行流程
1.先查找构造函数实例里的属性或方法,如果有,就立即返回。
2.如果构造函数的实例没有,就去它的原型对象里找,如果有,就立即返回

题目2

(function(){
    var a = b = 5;
})();
console.log(b); // 打印输出5

题目4

 var x=1,
    y=0,
    z=0;
function add(n){
    return n=n+1;
}
y=add(x);
z=x+y;
console.log("y1:"+y);
console.log("z1:"+z);

function add(n){
   return n=n+3;
}
y=add(x);
z=x+y;
console.log("y2:"+y);
console.log("z2:"+z);

打印输出 4,5,4,5
原因:
js函数声明提前有两种方式, 
1. var a = function () {} 这种方式声明函数只是把函数名提前了,而函数体并没有。
2. function a() {} 这种方式声明函数会将函数名和函数体都提前。

题目五

var fullname = 'John Doe';
var obj = {
   fullname: 'Colin Ihrig',
   prop: {
      fullname: 'Aurelio De Rosa',
      getFullname: function() {
         return this.fullname;
      }
   }
};
 
console.log(obj.prop.getFullname());
 
var test = obj.prop.getFullname;
 
console.log(test());

打印输出: Aurelio De Rosa; John Doe;
原因: this的指向问题
test是全局变量,test函数this指向的是全局变量fullname
obj.prop.getFullname的this指向的是prop对象。
this指向原则: 哪个对象调用函数,函数里面的this指向哪个对象。
若一定要让this指向全obj.prop, 可以这样:
test.call(obj.prop);
运用call函数改变this的指向,并执行函数。

题目六

console.log(typeof null); // object
console.log(typeof {});   //object
console.log(typeof []);   //object
console.log(typeof undefined); // undefined

题目七

function printing() {
   console.log(1);
   setTimeout(function() { console.log(2); }, 1000);
   setTimeout(function() { console.log(3); }, 0);
   console.log(4);
}
printing();
一次打印输出: 1, 4, 3, 2
原因: 
浏览器有一个事件循环用于检查事件队列,处理延迟的事件。UI事件(例如,点击,滚动等),Ajax回调,以及提供给setTimeout()和setInterval()的回调都会依次被事件循环处理。
当调用setTimeout()函数时,即使延迟的时间被设置为0,提供的回调也会被排队。
回调会呆在队列中,直到指定的时间用完后,引擎开始执行动作(如果它在当前不执行其他的动作)。
即使被指定时0,也会待在回调中。