<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--this的使用-->
<!--(1)this的指向
作为对象的方法调用
作为普通函数调用
构造器调用
Function.prototype.call或Function.prototype.apply调用
-->
<!--1)this作为对象的方法调用
当函数作为对象的方法被调用时,this指向该对象:
-->
<script>
var obj = {
a: 1,
getA: function () {
alert(this == obj); // true
alert(this.a); //1
}
}
obj.getA(); // 2. 作为普通函数调用使用
window.name = "gloabalName";
var getName = function () {
// 这哭的this指向的是window对象
return this.name;
} var myObject = {
name: "xiuxiu",
getNameA: function () {
// 这里的this指向的是myObject 对象
alert(this); // window
return this.name;
}
} console.log(getName()); var a = myObject.getNameA; //globalName
//console.log(a); // xiuxiu
console.log(a()); var innerText = "我是全局变量的innerText";
// callback方法的使用
var button = document.createElement("button");
button.innerText = "打开";
button.id = "btn";
document.body.appendChild(button);
button.onclick = function (ev) { // 定义一个that , 让这个that指向button对象
var that = this; // alert(this); button
// 这里的this指向的是触发这个事件的那个对象
console.log(this.innerText); var callback = function () {
// 这里的this指向的是window对象
// 注意:在ES5的strict模式下,this已经被规定不会指向全局对象,而是undefined
console.log(this.innerText); //undifined // 这里的that 指向的是这个按钮对象, 不是window对象
console.log(that.innerText);
}
callback();
} //3. 构造器调用
// 构造器里的this就指向返回的这个对象
var myClass = function (name, sex) {
this.name = name;
this.sex = sex; alert(this.name + " " + this.sex);
};
var male = new myClass("xiaohong", "male"); var myClass = function (name) {
//console.log(this.name); //undifined
this.name = name; console.log(this.name + " " + name); // 只有返回出去之后,这个name属性就会被外界修改
return {
name: "hahaha"
}
}
var cls = new myClass("xiuxiu");
alert(cls.name); // 4)Function.prototype.call和Function.prototype.apply调用
// 跟普通的函数调用相比,用Function.prototype.call或Function.prototype.apply可以动态的改变传入函数的this
var obj1 = {
name: "xiuxiu",
getName: function () {
return this.name;
}
}
var obj2 = {
name: "Jack"
}
console.log(obj1.name); // xiuxiu
console.log(obj1.getName.call(obj2)); // jack var obj3 = {
myname: "seven",
getName: function () {
return this.myname;
}
}
// 此时在调用this指向 obj3对象
console.log(obj3.getName()); // seven // 修改this的指向
// 这里是通过getname2这个普通函数区调用的, 此时this 指向的是window对象
// 但是全局中没有getname2这个方法
var getname2 = obj3.getName;
alert(getname2()); //undifined // document.getElementById的使用错误
var getId = function (id) {
//alert(this); // 这里的this指向的widnow
return document.getElementById(id);
}
var id = getId("btn");
console.log("id:" + id); // ButtonElement // 这里把这个函数的this修改为指向document对象
//var getId = document.getElementById;
//id = getId("btn");
//console.log("id:"+id); // this的使用理解.html?_ijt=7mjupf008evikdgvnqbeddk23d:146 Uncaught TypeError: Illegal invocation // 手动修改this 的指向
document.getElementById = (function (func) {
return function () {
// 这里强制让func对象指向documen对象
return func.apply(document, arguments);
}
})(document.getElementById); var getId = document.getElementById;
var button = getId("btn");
console.log(button); // <button id="btn">打开</button>
console.log(button.id); // 二、call和apply的使用
var func = function (a, b, c) { "use strict";
// 显示一下这个函数体内的this指向是个啥
alert(this);
console.log([a, b, c]);
}
// ƒ (a, b, c) {
/*console.log([a, b, c]);
}*/
console.log(func);
// func()表示直接去调用这个函数
console.log(func()); // undifined // 通过apply方法可以去修改这个函数体内的 this 的指向,可以任意修改, window, document
// 第一个参数也是代表函数体内的this指向,从第二个参数开始往后,每个参数被依次传入函数
func.apply(null, [1, 2, 3]); // this指向window
// 在严格模式"use strict"下上面的this指向为null, 不使用严格模式会指向window
func.apply(null, [1]); // this指向window //如果我们传入的第一个参数为null,函数体内的this会指向默认的宿主对象。在浏览器中则是window
func.apply(null, [0, 1]); // this指向window
//console.log(func());
func.apply(document, [0, 1, 2]); // this指向document
func.apply(this, [0, 1]); // this指向window // 利用函数求出最大值
console.log(Math.max.apply(null, [1, 2, 3]));
console.log(Math.max(1, 2, 3)); // 三、call和apply在实际开发中的用途
// 1.)修改 this的指向
var obj1 = {
//alert(this);
name: "seven"
}
var obj2 = {
//alert(this);
name: "haha" } window.name = "window";
var getName = function () {
console.log(this.name);
}
// 全局调用函数
getName(); // this指向的是window
getName.call(obj1); // this指向的是obj1对象
getName.call(obj2); // this指向的是obj2对象 // 添加一个事件
document.addEventListener("click", function (ev) {
// 这里的this 指向的是触发这个事件的那个对象
console.log(this); // document function Add(a, b) {
console.log(this);
} // 这个相当于是全局调用,thisz指向的是window对象
Add(10, 1); // window
// 修正这个this 的指向
// 这里的this指向的还是触发这个事件的那个对象
Add.call(this); // document
}); // 2).Function.prototype.bind
// Function.prototype.bind,用来指定函数内部的this指向
Function.prototypebind = function (context) {
var self = this; return function () {
console.log(context+"is"+ this); // 修改this(self)的指向为context对象
return self.apply(context, arguments);
}
} var obj = {
name: "xiuxiuDesign"
}
var getName = function () {
// 修改this的指向为obj对象
console.log(this.name);
}.bind(obj);
getName(); // 3).借用其它对象的方法
var A = function (name) {
this.name = name;
}
var B = function () {
// 修改A这个的this对象指向B
A.apply(this, arguments); // Arguments ["xiuxiu is a good man", callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(arguments);
} B.prototype.getName = function () {
//
return this.name;
}
var b = new B("xiuxiu is a good man");
console.log(b.getName()); // 想往argumments中添加一个新的元素,通常会借用Array.prototype.push
(function () {
Array.prototype.push.call(arguments, 3);
console.log(arguments);
})(1, 2, 1, 3) // 想把arguments转成真正的数组的时候,可以借用Array.prototype.slice方法,想截取arguments列表中的头一个元素时,可以使用Array.prototype.shift方法,这种机制的内部原理,我们可以翻开V8引擎源码,以Array.prototype.push方法为例
var a = {};
// 修改Array这个数组的指向, 让这个数组的push的this指向a的引用, 也就是a这个对象
Array.prototype.push.call(a, 'first');
Array.prototype.push.call(a, 'second'); // 通过调用Array的push 方法, 同时修改了this 的指向为a这个对象的引用
console.log(a.length);
console.log(a[0]); // JavaScript的一种继承方式
var AA = function (name, age) {
this.name = name;
this.age = age;
}
AA.prototype = {
getName : function () {
alert(this.name);
}
} var BB = function () {
}
// 让BB对象继承于AA对象
BB.prototype = new AA("AAA", 19); var aa = new AA("xiuxiu", 18);
console.log(aa.name +" "+aa.age); // xiuxiu, 18
var bb = new BB();
console.log(bb.name+" "+bb.age); // AAA 19 </script> </body>
</html>

JavaScript进阶【四】JavaScript中的this,apply,call的深入剖析的更多相关文章

  1. JavaScript进阶(五)js中取小数整数部分函数

    js中取小数整数部分函数 丢弃小数部分,保留整数部分 js:parseInt(7/2) 向上取整,有小数就整数部分加1 js: Math.ceil(7/2) 四舍五入 js: Math.round(7 ...

  2. JavaScript进阶(四)js字符串转换成数字的三种方法

    js字符串转换成数字的三种方法 在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b. ...

  3. 二、JavaScript语言--JS基础--JavaScript进阶篇--JavaScript内置对象

    1.什么事对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等: 对象的方 ...

  4. Javascript进阶篇——( JavaScript内置对象---上-Date,string,charAt,indexOf,split,substring,substr)笔记整理

    什么是对象JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法.对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等:对象的方法:能够在 ...

  5. Javascript进阶篇——( JavaScript内置对象---下)--Array数组对象---笔记整理

    Array 数组对象数组对象是一个对象的集合,里边的对象可以是不同类型的.数组的每一个成员对象都有一个“下标”,用来表示它在数组中的位置,是从零开始的数组定义的方法: 1. 定义了一个空数组: var ...

  6. Javascript进阶篇——( JavaScript内置对象---下)--Math对象---笔记整理

    Math对象使用 Math 的属性和方法: <script type="text/javascript"> var mypi=Math.PI; var myabs=Ma ...

  7. mysql进阶(四)mysql中select

    mysql中select * for update 注:  FOR UPDATE 仅适用于InnoDB,且必须在事务区块(BEGIN/COMMIT)中才能生效. 作用 锁定该语句所选择到的对象.防止在 ...

  8. 面试官:能解释一下javascript中bind、apply和call这三个函数的用法吗

    一.前言    不知道大家还记不记得前几篇的文章:<面试官:能解释一下javascript中的this吗> 那今天这篇文章虽然是介绍javascript中bind.apply和call函数 ...

  9. JavaScript进阶系列02,函数作为参数以及在数组中的应用

    有时候,把函数作为参数可以让代码更简洁. var calculator = { calculate: function(x, y, fn) { return fn(x, y); } }; var su ...

随机推荐

  1. 通过Sqoop实现Mysql / Oracle 与HDFS / Hbase互导数据

    通过Sqoop实现Mysql / Oracle 与HDFS / Hbase互导数据\ 下文将重点说明通过Sqoop实现Mysql与HDFS互导数据,Mysql与Hbase,Oracle与Hbase的互 ...

  2. n!最末尾非0数

    最小周期串:如果s是ss的周期串,那么ss就可以表示成几个周期的s,如果s是ss的最小周期串,那么s就是ss的周期串中最小的一个.例,ZgxZgxZgxZgx的最小周期串是Zgx.{很好理解} 给你一 ...

  3. 洛谷 P2633 Count on a tree

    P2633 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中last ...

  4. 网络编程中的CAP & 有趣的存储框架(关系型、NoSQL)全图

    第七篇 CAP https://zhuanlan.zhihu.com/p/20399316?refer=auxten   CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer’s t ...

  5. PHP反射类的理解(代码篇)

    <?php/** * Created by PhpStorm. * User: * Date: 2017/6/12 * Time: 14:34 * 关于反射类的理解 */class Person ...

  6. C#实体转换

    using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using S ...

  7. luogu1447 能量采集

    题目大意 给出m,n,对于每一个整数x∈[1,m],y∈[1,n]都有一点(x,y).处理每个点所需要的能量为2*k+1,k为该点到原点经过的点的数量(不包括该点本身).求处理所有点所需要的能量和. ...

  8. Swift_ios_二进制,十进制,十六进制之间的转换

    这里所说的转换,并不是Swift中字面量之间的转换.如果是字面量之间的转换,ios系统中已经自动帮我们转换了. 例如let number1:Int = 8let number2:Int = 0b100 ...

  9. Python中的traceback模块

    traceback模块被用来跟踪异常返回信息. 如下例所示: 1.直接打印异常信息 import traceback try: raise SyntaxError, "traceback t ...

  10. xss 记录cookie

    <p> <img src="http://act.ci123.com/global/ueditor_new/php/upload/98591403834900.jpg&qu ...