this的绑定与丢失问题

this的绑定与丢失问题,第1张

this 四种绑定

1、new绑定:new方式是优先级最高的一种调用方式,构造函数只是一些使用new *** 作符时被调用的函数。

只要使用new方式调用一个构造函数,this一定指向new调用函数新创建的对象。

使用new来调用函数的时候会自动执行下面的 *** 作:

①、创建(或这说构造)一个全新的对象

②、这个新的对象会被执行[[Prototype]]连接

③、这个新对象会绑定到函数调用的this。

④、如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象

2、显式绑定:显式绑定是通过call()和apply()方法强制制定某些对象对函数进行调用,this则强制指向 调用函数的对象。

显式绑定中强制绑定---硬绑定(解决隐式绑定丢失问题)

创建了函数bar()并在内部手动调用了foo.call(obj),因此强制把foo的this绑定到了obj上。无论之后如何调用bar,总会手动在obj上调用foo。 硬绑定的典型应用场景就是创建一个包裹函数,负责接收参数并返回值

另一种 使用方法是创建一个可以重复的辅助函数

由于硬绑定的使用很多,在ES5中提供了内置的方法Function.prototype.bind

bind(...)会返回一个硬编码的新函数,它会把你指定的参数设置为this的上下文并调用原始函数。

3、隐式绑定:指通过为对象添加属性,该属性的值即为要调用的函数,进而使用该对象调用函数

4、默认绑定:其他规则无法应用的时候

1、隐式丢失:在隐式绑定时,使用了依次引用赋值或者传参 *** 作。丢失之后会使用默认绑定,把this绑定到全局对象或者undefined上,取决于是否是严格模式。

①、引用赋值

newData实际上引用的是foo本身,相当于var newData = foo

data对象作为中间桥,data.foo起传递作用,newData与data没有关系,newData本身没有a属性

newData()输入的是window下的属性a的值。

②、参数传递

参数传递其实就是一种隐式赋值,因此我们传入的函数也会被隐式赋值。

如果把函数传入内置的函数中结果是一样的

回调含糊丢失this绑定是非常常见的。也有可能存在调用回调函数的函数可能会修改this。

在一些流行的JavaScript库中事件处理器常会把回调函数的this强制绑定到触发事件的DOM元素上

2、间接引用:指一个对象的方法引用了另一个对象存在的方法。此时的this指向window或者undefined

判断使用默认规则不是调用函数位置是否处于严格模式下,而是整个函数体是否处于严格模式,

3、=> 使用词法作用域取代传统的this机制,无法使用上述所说的this的优先级原则

注:=>函数中,根据外层父亲作用域来决定this的指向问题。

foo()内部创建的箭头函数会捕获调用foo()时的this,由于foo()的this绑定到obj1上,bar(引用箭头函数)的this

也会绑定到obj1上,箭头函数的绑定无法被修改。(new 也不行!)

jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM *** 作中会经常用到attr(),attr()有4个表达式。

1. attr( 属性名 )//获取属性的值(取得第一个匹配元素的属性值。通过这个方法可以方便地从第一个匹配元素中获取一个属性的值。如果元素没有相应属性,则返回 undefined )

2. attr( 属性名, 属性值 )//设置属性的值 (为所有匹配的元素设置一个属性值。)

3. attr( 属性名 , 函数值 ) //设置属性的函数值 (为所有匹配的元素设置一个计算的属性值。不提供值,而是提供一个函数,由这个函数计算的值作为属性值。)

4. attr(properties) //给指定元素设置多个属性值,即:{属性名一: “属性值一” , 属性名二: “属性值二” , … … }。(这是一种在所有匹配元素中批量设置很多属性的最佳方式。 注意,如果你要设置对象的class属性,你必须使用'className' 作为属性名。或者你可以直接使用'class'或者'id'。)

示例代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8" />

<title>jquery中attr()方法</title>

<script src="js/jquery-1.4.2.min.js" language="javascript" type="text/javascript" ></script>

<style>

p{color:red}

li{color:blue}

.lili{font-weight:boldcolor:red}

#lili{font-weight:boldcolor:red}

</style>

</head>

<body>

<p title="你最喜欢的水果是。">你最喜欢的水果是?</p>

<ul>

<li title="苹果汁">苹果</li>

<li title="橘子汁" alt="123">橘子</li>

<li title="菠萝汁">菠萝</li>

</ul>

<script>

...

</script>

</body>

<html>

1.attr(name)//获取属性的值

1.1使用attr(name)获取title值:

<script>

alert($("ul li:eq(1)").attr("title"))

</script>

结果: 显示 橘子汁

1.2使用attr(name)获取alt值:

<script>

alert($("ul li:eq(1)").attr("alt"))

</script>

结果:

显示123

2. attr(name,value) //设置属性的值

2.1使用attr(name,value)修改title值为:不吃橘子

<script>

$("ul li:eq(1)").attr("title","不吃橘子")

alert($("ul li:eq(1)").attr("title"))

</script>

结果:

显示不吃橘子

3. attr(name,fn) //设置属性的函数值

3.1把alt属性的值设置为title属性的值。

<script>

$("ul li:eq(1)").attr("title",function(){ return this.alt})

alert($("ul li:eq(1)").attr("title"))

</script>

结果:

显示123

4.attr(properties) //将一个“名/值”形式的对象设置为所有匹配元素的属性

4.1获取<ul>里第2个<li>设置title和alt属性。

<script>

$("ul li:eq(1)").attr({title:"不喝橘子汁",alt:"不是123"})

alert($("ul li:eq(1)").attr("title"))

alert($("ul li:eq(1)").attr("alt"))

</script>

结果:

显示2个,不喝橘子汁 不是123

4.2获取<ul>里第2个<li>设置class。

<script>

$("ul li:eq(1)").attr({className:"lili"})

</script>

结果:

<li title="苹果汁">苹果</li>

<li class="lili" alt="123" title="橘子汁">橘子</li>

<li title="菠萝汁">菠萝</li>

4.3获取<ul>里第2个<li>设置id。

<script>

$("ul li:eq(1)").attr({id:"lili"})

</script>

结果:

<li title="苹果汁">苹果</li>

<li class="lili" alt="123" title="橘子汁">橘子</li>

<li title="菠萝汁">菠萝</li>

4.4获取<ul>里第2个<li>设置style。

<script>

$("ul li:eq(1)").attr({style:"color:red"})

</script>

结果:

<li title="苹果汁">苹果</li>

<li class="lili" alt="123" title="橘子汁" style="color:red">橘子</li>

<li title="菠萝汁">菠萝</li>

在 li中添加alt是错误的,它只能用在img、area和input元素中(包括applet元素)。对于input元素,alt属性意在用来替换提交按钮的图片。在这里为了很详细说明attr()方法,没有合适的属性,所有用了alt进行举例,只供学习参考attr()方法用法。

在此说明下alt和tite的区别。

alt:这是用以描述图形的文字,当图片无法显示时,这些文字会替代图片而被显示。当鼠标移至图片上该些文字亦会显示。

title:是鼠标放上去之后,会显示出来的文字。

那么怎么删除属性呢?

jquery中删除属性的关键词是: removeAttr 注意A是大写的. 看看怎么用的:

同样是用法一中的html代码, 我想删掉li的title属性, 那么就这样:

<script>

$("ul li:eq(1)").removeAttr("title")

</script>

就这么简单, attr 其实就是原生js中 getAttribute 的简化实现, 而removeAttr 就是 removeAttribute 的简写了。

那么是否有跟attr()相似的属性呢?

jquery中val()与之类似,

$(this).val()获取某个元素节点的value值,相当于$(this).attr("value")

$(this).val(value)设置某个元素节点的value值,相当于$(this).attr("value",value)

this指直译是“这个”,在java中指“当前的”。不管在哪里,只要用到this,指的一定就是当前的这个对象。最常见的用法是在写java bean中。比如下面的代码

public class Student{

    private String name

    private int age

    public Student(){}

    public Student(String name,int age){

        this()

        this.setName(name)

        this.age = age

    }

    public void setName(String name){

        this.name = name

    }

    public int getAge() {

        return this.age

    }

}

上面的代码是一个java bean。所谓的java bean就是一个类,这个类有一些属性,方法只有这些属性的Getter 或者Setter (从Object类继承的方法不算在此列)。

这个bean有两个属性,在构造器中为属性赋值的时候写的this.setName(name).意思是调用当前你创建的这个对象的Setter给这个对象的属性赋值。而setName里面的this.name = name这一句,等号之前的this.name表示当前对象的name,也就是在类里面定义的private String name这个变量,而等号之后的name表示从外界调用这个方法时候传进来的参数。所以这句话的意思就是将外界传来的字符串变量的值赋给当前对象的name属性。

那么构造器第一行的this()是做什么的呢?这句话是调用当前这个对象的无参构造,就是调用上面的public Student(){}这个构造器。在这段代码里this()体现不出来什么作用。但是我们知道构造器的作用是在构造对象的时候给属性赋值的。如果上面个无参构造里面写一些赋值语句的话那么这里就可以避免代码的重复了。但是请注意,调用this()的时候一定要写在该方法的第一行,否则会报错。

另外,this关键字不能使用在有static关键字修饰的方法和代码块里面。因为static是这个类的所有对象共用的,而this指的只是当前这个对象的“私人”的一些东西,在属性上面就冲突了。

说到this就得顺带提一下super关键字了。super关键字的用法同this差不多,同样不能与static一起使用。同样有super()的写法,且需要写在方法第一行。但是super所指示的东西可不一样,一般指的是当前这个类的直接父类。如果在子类中需要使用父类的构造器或者属性的时候可以使用super关键字。比如下面的代码:

public class Student extends Object{

        public Student(){

            super()

        }

     @Override

public boolean equals(Object obj) {

return super.equals(obj)

}

}

上面这段代码就是在实现equals方法的时候调用其直接父类的Object类的equals方法。而在构造这个类的对象的时候也调用了其父类的构造方法。

注:上面代码中的extends Object其实完全不必写,因为所有的类都直接或者间接是Object类的子类(除了Object类本身)。如果不写extends的话默认继承Object类。这里为了需要所以这样写


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/bake/11825278.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存