1)

  1. function C1(name) {
  2. //没有传参 name为undefined
  3. if (name) {
  4. this.name = name;
  5. }
  6. //if么有进入,所以没有私有的name 找的公有的name
  7. }
  8. function C2(name) {
  9. this.name = name;
  10. }
  11. function C3(name) {
  12. this.name = name || 'join'; //给私有对象设置了私有属性 this.name=undefined{没有传参}=>this.name=undefined||'join' 走第二个 此时私有属性的this.name='join'
  13. }
  14. C1.prototype.name = 'Tom';
  15. C2.prototype.name = 'Tom';
  16. C3.prototype.name = 'Tom';
  17. alert((new C1().name) + (new C2().name) + (new C3().name)); //TomUndefiendJoin

1.png

2)

function Fn(num) {
    this.x = this.y = num;
}
Fn.prototype = {
    x: 20,
    sum: function () {
        console.log(this.x + this.y);
    }
};
let f = new Fn(10);
console.log(f.sum === Fn.prototype.sum);//true 找的是同一个地址
f.sum();//20=>此时的this=f 相当于=》this.x+this.y=>f.x+f.y=10+10=>20
Fn.prototype.sum();//NaN=>此时的this 相当于=>Fn.prototype 相当于 Fn.prototype.x+Fn.prototype.y=20+undefined;NaN
console.log(f.constructor); //object 因为更改了protype的引用地址{自己创建的对象}的__proto__指向的是Object.prototype原型上

2.png

3)

function Fn() {
    let a = 1;
    this.a = a;
}
Fn.prototype.say = function () {
    this.a = 2;
}
Fn.prototype = new Fn;
let f1 = new Fn;
Fn.prototype.b = function () {
    this.a = 3;
};
console.log(f1.a);//1
console.log(f1.prototype);//undefined
console.log(f1.b);//f1.a 变为了3
console.log(f1.hasOwnProperty('b'));//false
console.log('b' in f1);//true
console.log(f1.constructor == Fn); //true

3.png

4)

function fun() {
    this.a = 0;
    this.b = function () {
        alert(this.a);
    }
}
fun.prototype = {
    b: function () {
        this.a = 20;
        alert(this.a);
    },
    c: function () {
        this.a = 30;
        alert(this.a)
    }
}
var my_fun = new fun();
my_fun.b();//0
my_fun.c(); //30

4.png

5)给Number的原型上增加plus&minus方法

let n = 10;
let m = n.plus(10).minus(5);
console.log(m); //=>15(10+10-5)
Number.prototype.plus=function(num){
    //this相当于n
    //如果没有传参 则num为0
    num=num||0;
    return this+num;
};
 //形参赋值的方法
Number.prototype.minus=function(num=0){
      return this-num;
}
let n = 10;
let m = n.plus(10).minus(5);
console.log(m); //=>15(10+10-5)

6) url参数处理 https://www.yuque.com/go/doc/44635069

let url="http://www.zhufengpeixun.cn/?lx=1&from=wx#video";
     console.log(url.queryURLParams("from")); //=>"wx"
console.log(url.queryURLParams("_HASH")); //=>"video"

1.方案1 用split截取

  let url="http: www.zhufengpeixun.cn/?lx=1&from=wx#video";
  String.prototype.queryURLParams=function(attr) {
      //this是处理的字符串
      let ary = this.split('?')[1].split('#');
         ary=["lx=1&from=wx", "video"]
      let obj ={_HASH:ary[1]};
      ary[0].split('&')=['lx=1','from=wx']
        ary[0].split('&').forEach(item => {
        let ary = item.split('=');
            ary=['lx','1']
          obj[ary[0]] = ary[1];
      })
      console.log(ary,obj);
      return obj[attr];
  }
  console.log(url.queryURLParams("from"));  =>"wx"
  console.log(url.queryURLParams("_HASH"));  =>"video"

2)方案2 例如a标签的href

 String.prototype.queryURLParams = function (parms) {
            let link = document.createElement('a');
            link.href = url;

            let undtext = link.search.substring(1),
                hatext = link.hash.substring(1);

            let obj = {};
            hatext ? obj['_HASH'] = hatext : null;
            if (undtext) {
                undtext.split('&').forEach(item => {
                    let arr = item.split('=');
                    obj[arr[0]] = arr[1];
                })
            }
            return parms ? obj[parms] : '';;
        }
        let url = "http://www.zhufengpeixun.cn/?lx=1&from=wx#video";
        console.log(url.queryURLParams("from")); //=>"wx"
        console.log(url.queryURLParams("_HASH")); //=>"video"

7)下面代码输出结果是什么?为啥? 「有难度」

let obj = {
    2: 3,
    3: 4,
    length: 2,
    push: Array.prototype.push
}
obj.push(1);
obj.push(2);
console.log(obj); //{2: 1, 3: 2, length: 4, push: ƒ}
  let obj = {
      2: 3,
      3: 4,
      100:1,
      length: 40,
        //把内置类Array原型上的push方法给了obj一个私有的push
      push: Array.prototype.push
  }
  //数组使用push是给数组的末尾增加一项
  ary.push(1)
  this[this.length] = 1
  this.length++;
  //obj调用push方法不一定是给obj增加一项,他的结果需要根据具体的属性来判断
  obj.push(1); obj[obj.length]=1 => obj[40]=1,obj.length+1=41
  obj.push(2); obj[obj.length]=obj[41]=2;obj.length+1=42
  console.log(obj);

8)a等于什么值会让下面条件成立 「有难度」

两个等号和三个等号的区别

    1. == 进行比较的时候  两边数据类型不一致 先默认转换为相同的数据类型,然后再进行比较
    2.除了 对象==字符串,是把对象转换为字符串,其余的都是转换为数字(其中比较特殊的是对象,对象转换为数字,首先把它转换为字符串 => toString方法)

    遵循V8 转Number 的步骤 [Symbol.toprimitive]  ValueOF toString
  var a = ?;
  if (a == 1 && a == 2 && a == 3) {
            console.log('OK');
    }

解决1.1 此时 toString 就不会再调取Object原型里的.toString 方法了

var a = {
           n:0,
           toString:function(){
                return ++this.n;
           }
        };
        if (a == 1 && a == 2 && a == 3) {
            console.log('OK');
        }
 //让每一次toString 都执行shift ,清除数组的第一项,每一次
var a = [1,2,3];
a.toString=a.shift;
if (a == 1 && a == 2 && a == 3) {
      console.log('OK');
 }

解决1.2 此时 valueOf 就不会再调取V8【机制】valueOf 方法了

var a = {
            n: 0,
            valueOf: function () {
                return ++this.n;
            }
        };
if (a == 1 && a == 2 && a == 3) {
       console.log('OK');
}