高级2

作者: 安石0 | 来源:发表于2017-07-11 23:14 被阅读0次

this 相关问题

1:构造函数调用: new S() ==>指向创建对象本身{a:'a'}
2:方法调用:method,property

var p={
               s:function(){ 
                       console.log(this)
                               }
}  
p.s()==>this指向调用方

3:apply,call的调用
p.s.call({a:1},1,2)
p.s.apply({a:1},[1,2]) //手动指定this
4: 函数调用
var cache=p.s;
cache()==>this指向全局
p.s()==>this指向p
问题1: apply、call 、bind有什么作用,什么区别
apply:在调用一个存在的函数时,你可以为其指定一个 this对象。 this指当前对象,也就是正在调用这个函数的对象。 使用 apply, 你可以只写一次这个方法然后在另一个对象中继承它,而不用在新对象中重复写该方法。

fun.apply(thisArg, [argsArray])
var arr=[1,2,3,6,0,3]
Math.max.apply(null,arr)//6
//传入null,undefined为相当于全局作用域this=window

thisArg
fun 函数运行时指定的 this值。需要注意的是,指定的 this值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
argsArray一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null或 undefine,则表示不需要传入任何参数
apply 与 call()非常相似,不同之处在于提供参数的方式。apply 使用参数数组而不是一组参数列表(原文:a named set of parameters)。apply
可以使用数组字面量(array literal),如 fun.apply(this, ['eat', 'bananas'])
,或数组对象, 如 fun.apply(this, new Array('eat', 'bananas'))

call:

fun.call(thisArg[, arg1[, arg2[, ...]]])
var arr=[1,2,3,6,0,3]
Math.max.call(this,arr[0],arr[2])//3

后面传入的参数必须为数组value的形式,不能是一个数组,其他的与apply相似
bind():bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

/*
语法:fun.bind(thisArg[, arg1[, arg2[, ...]]])
thisArg当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用new操作符调用绑定函数时,该参数无效。arg1, arg2, ...当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
*/
function Person(name, age) {
  this.name = name;
  this.age = age;
}

var _Person = Person.bind(null, 'hanzichi');
var p = new _Person(30); // Person {name: "hanzichi", age: 30}

问题2: 以下代码输出什么?

var john = { 
  firstName: "John" 
}
function func() { 
  alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()//john:hi!

john.sayHi()=function(){
alert(this.firstName + ": hi!")
}
john调用了sayHi()方法,所以该方法内部this是john
问题3: 下面代码输出什么,为什么

func()
function func() {
alert(this)
}
弹出:object window//
函数声明前置,func()相当于是window.fun(),window调用,
等价于call 方法的func.call(undefined,null)
第一个参数为undefined或者null,作用域为window
问题4:下面代码输出什么

document.addEventListener('click', function(e){
    console.log(this);
    setTimeout(function(){
        console.log(this);
    }, 200);
}, false);
//输出#document   window
/*
首先:settimeout的执行肯定是在函数执行完再执行的
第二:document调用addEventListener方法所以this是document,
第三:  setTimeout()相当于是setTimeout.call(null,function,delay),所以this时是window.,document的onclick
如果想输出的this的document可以用bind()方法改写*/
document.addEventListener('click', function(e){
    console.log(this);
    setTimeout(function(){
        console.log(this);
    }.bind(this), 200);
}, false);

问题5:下面代码输出什么,why

var john = { 
  firstName: "John" 
}
function func() { 
  alert( this.firstName )
}
func.call(john)
fun.call(thisArg[, arg1[, arg2[, ...]]])
参数
thisArg在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于[非严格模式下]则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。arg1, arg2, ...指定的参数列表。

func.call传入的第一个参数为jhon,jhon为引用类型,所以func(obj)this值的是传入的参数,this.firstName='John'
问题6: 以下代码有什么问题,如何修改

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //this指什么
      this.showMsg();
    })
  },
  showMsg: function(){
    console.log('饥人谷');
  }
}

上图中是btn调用on()方法,所以this指的是$btn节点,下面的 this.showMsg();,因为$btn没有定义过该方法,所以会报错
如果想要调用this.showMsg()

//方法1:
            var module= {
                
  bind: function(){
    var _this=this
    $btn.on('click', function(){
      console.log(this) //this指什么
      _this.showMsg()
    })
  },
  showMsg: function(){
    console.log('饥人谷');
  }
}
//方法2:
            var $btn=$('.btn')
            var module= {
                
  bind: function(){

    $btn.on('click', function(){
      console.log(this) //this指什么
      this.showMsg()
    }.bind(this))//on方法外面绑定this,指定this值为该对象
  },
  showMsg: function(){
    console.log('饥人谷');
  }
}
            module.bind()

原型链相关问题

问题7:有如下代码,解释Person、 prototype、proto、p、constructor之间的关联。

function Person(name){
    this.name = name;
}
Person.prototype.sayName = function(){
    console.log('My name is :' + this.name);
}
var p = new Person("若愚")
p.sayName();
1499838686676.jpg

问题8: 上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。
p中没有定义过toString()方法,所以会通过p.proto向上寻找,p.proto指向Person.prototype,Person.prototype中也没有定义过toString(),所以会向上寻找Person.prototype.proto找到Object,object有一个tosting的方法,如果object没有定义的,则会找不到,报错

QQ图片20170712141707.jpg
原型是什么prototype,通过原型这种机制,JavaScript 中的对象从其他对象继承功能特性
问题9:对String做扩展,实现如下方式获取字符串中频率最高的字符
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次
String.prototype.getMostOften=function(str){
var arr=[];
  for(var i=0;i<str.length;i++){
    
if(arr[str[i]]){
  arr[str[i]]++
}else{
  arr[str[i]]=1
}
  }
  var arr2=[]
  for(var i in arr){
    arr2.push(arr[i])
  }
  var max=Math.max.apply(null,arr2)
  return max
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次

问题10: instanceOf有什么作用?内部逻辑是如何实现的?
instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

var a=[]
a instanceof Array//true;
a instanceof Object//true;
Array._proto_指向了Object

所以两个都是返回都是true

继承相关问题

问题11:继承有什么作用?
一个对象不用声明就能拥有另一个对象的属性和方法为继承,在javascript中通过原型链来实现继承,JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依此层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
问题12: 下面两种写法有什么区别?

//方法1  构造函数方式声明属性和方法
function People(name, sex){
    this.name = name;
    this.sex = sex;
    this.printName = function(){
        console.log(this.name);
    }
}
var p1 = new People('饥人谷', 2)

//方法2  原型方式声明属性和方法
function Person(name, sex){
    this.name = name;
    this.sex = sex;
}

Person.prototype.printName = function(){
    console.log(this.name);
}
var p1 = new Person('若愚', 27);
p2.printName
function (){
        console.log(this.name);
    }
p1.printName
function (){
        console.log(this.name);
    }
p2.printName===p1.printName//false
//p1,p2通过new Person()的方式创建一个对象,然后返回的一个对象,返回的两个函数实际上声明两次,所以这两个方法内容一样,但是相等
var p4= new Person('火锅', 25);
p4.printName===p3.printName//true
通过原型方式声明的方法,因为本身并没有声明这个方法,而是通过object._proto_向上寻找,p3._proto_和p4._proto_对应原型的prototype对象其实是一个,所以他们相等,而且只需要声明一次。

问题13: Object.create 有什么作用?兼容性如何?
object.create() 方法使用指定的原型对象和其属性创建了一个新的对象。
语法
Object.create(proto, [ propertiesObject ])
参数
proto
一个对象,应该是新创建的对象的原型。
propertiesObject
可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符(这些属性描述符的结构与Object.defineProperties()的第二个参数一样)。注意:该参数对象不能是 undefined
,另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。
例如:

Object.create({a:1})//创建一个新的对象,该对象的_proto_属性指向传入的参数,即是新创建对象的原型,所以*第一个参数必须是对象

不支持ie8及以下版本
问题14: hasOwnProperty有什么作用? 如何使用?
hasOwnProperty() 方法会返回一个布尔值,指示对象是否具有指定的属性作为自身(不继承)属性。

function A(name){}
function A(name){this.name=name}
A.prototype={age:10,sex:'man'}
Object {age: 10, sex: "man"}
var a=new A('狗娃')
a.hasOwnProperty('name')//true
a.hasOwnProperty('age')//false

问题15:如下代码中call的作用是什么?

function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex); //这里的 call 有什么作用
this.age = age;
}

function Person(name, sex){
    this.name = name;
    this.sex = sex;
}
function Male(name, sex, age){
    Person.call(this, name, sex);    //这里的 call 有什么作用
    this.age = age;
}
var hhh=new Male('二狗子','男','25')

调用Person函数,以call的方式,第一个传入的参数this此时指的是Male内,当用new关键字的时候,this 指的就是hhh了
问题16: 补全代码,实现继承

function Person(name, sex){
// todo ...
}

Person.prototype.getName = function(){
// todo ...
};

function Male(name, sex, age){
//todo ...
}

//todo ...
Male.prototype.getAge = function(){
//todo ...
};

var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();

function Person(name, sex){
    this.name=name;this.sex=sex
}

Person.prototype.getName = function(){
    console.log(this.name)
};    

function Male(name, sex, age){this.age=age;
   Person.call(this,name,sex);this.printName=function(){console.log(this.name)}
}

//todo ...
Male.prototype.getAge = function(){
    console.log(this.age)
};

var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();

问题:

  1. 问题6方法三的代码调用call的行为是多余的。
  2. 问题8中toString不是来自Object,而是来自Object.prototype。
  3. 原型链解释错误。
  4. 问题9代码错误,不符合题意。
  5. 问题10老毛病,Array.proto指向了Object解释错误。
    6.第十二题 // p1,p2通过new Person()的方式创建一个对象,然后返回的一个对象,返回的两个函数实际上声明两次,所以这两个方法内容一样,但是相等。 相等??确定?

相关文章

  • 高级2

    this 相关问题 问题1: apply、call 、bind有什么作用,什么区别 bindFunction.pr...

  • 高级2

    问题1: apply、call 、bind有什么作用,什么区别. Function.prototype.bindb...

  • 高级2

    this 相关问题 1:构造函数调用: new S() ==>指向创建对象本身{a:'a'}2:方法调用:meth...

  • 2020-05-22

    自然阳光:级别区分 主任2万 高级主任:5万→2个主任 经理:10万→3个主任*2万(包含高级主任业绩) 高级经理...

  • IOS开发 UIGesture高级手势

    本字学习内容: 1.UIGesture高级手势类型 2.UIGesture高级手势属性 3.UIGesture高级...

  • Python 高级 2

    1.高级Linux命令及命令选项的使用 <1>重定向命令:> Linux允许将命令执行结果重定向到一个文件,本应显...

  • 高级2修改

    问题: 1. 问题6方法三的代码调用call的行为是多余的。2. 问题8中toString不是来自Object,而...

  • 高级-任务2

    this 相关问题 问题1: apply、call 、bind有什么作用,什么区别 apply和call的第一个参...

  • JavaScript高级2

    原型链 组成:一个或多个原型组成的结构 作用:描述了对象属性的查找方式 原型链的终点:Object.prototy...

  • 高级隐喻2

    20190530《高级隐喻——故事转化生命》第五章转化死亡、第六章连接内在真相、第七章诚信和承诺、第八章一个意识的...

网友评论

      本文标题:高级2

      本文链接:https://www.haomeiwen.com/subject/alamhxtx.html