当前位置: 首页 > 编程日记 > 正文

javascript中this那些事

定义

this是函数执行的上下文。

调用方式

1. 作为函数调用,指向window(严格模式报undefined的错)。

var name='hello';
function a() {    console.log(this.name)   
}
a();     //hellovar c={    name:'haha',    d: function(){ a(); } 
}
c.d();    //hello
复制代码

2. 作为属性调用,指向该对象。

var name='hello';
function a(){   console.log(this.name)
}
var b={    name:'world',    a:a    
}
b.a();    //world
复制代码

有个陷阱,作为函数别名调用时,会丢失this。

var name='hello';
function a(){   console.log(this.name)
}
var b={    name:'world',    a:a    
}var test=b.a;
test();     //hello
复制代码

3. 作为构造函数调用,会把属性挂到new出来的实例上。

function A(){    this.name='xiaoming'
}
var a=new A();
console.log(a.name);    //xiaoming
复制代码

如果构造函数有return,且return对象(包括{}、[]),那么new的实例就是return的值.

function A(){    this.name='xiaoming';return {}  
}
var a=new A();
console.log(a.name)    //undefined
复制代码

如果return的是字符串、“”、null、undefined,new的实例和无return时new的实例一样。

function A(){    this.name='xiaoming';return null
}
var a=new A();
console.log(a.name);    //xiaoming
复制代码

其实new做了三件事:

  1. 创建一个新对象:var obj={}

  2. 将obj的__proto__指向A.prototype:obj.__proto__=A.prototype;该步骤是为了继承构造函数A原型链。

  3. 将this指向该新对象执行A:A.call(obj)

function Animal(){    this.animal="animal";
}
Animal.prototype.name="9"; //Animal构造函数原型的属性name
function Dog(){    this.dog="dog";    
}
Dog.prototype.__proto__=Animal.prototype;var d=new Dog();
var obj={};
obj.__proto__=Dog.prototype;
Dog.call(obj);
复制代码

上面的例子中,对象d和对象obj完全一样,结果都是下图的实例,都能访问Animal构造函数原型的属性name和方法。

改变this指向的三种方式

1.call

使用:Function.call(obj,arg0,arg1...)

将Function的this指向obj,第一个参数是this指向,后面的参数是传入Function的参数,一般用于参数个数固定的的函数。对于改变this指向,我个人理解是把函数里所有用到this的地方替换为obj。

2.apply

使用:Function.apply(obj,[arg0,arg1...])

将Function的this指向obj,第一个参数是this指向,第二个参数是传入Function的参数组成的数组,一般用于参数个数不固定的的函数。

3.bind

使用:Funtion(arg0,arg1...).bind(obj)

误区

误区1:this指向函数本身?

var name='hello'
function a(){    console.log(this.name);    
}
a.name='world';
a() ;    //打印hello
console.log(a.name)     //world
复制代码

题外话:

Object和Function既是对象,又是函数,两者内部同时含有proto和prototype属性。 Function.prototype指向”内置函数“。而Object.prototype指向”根源对象“

Object.__proto__ === Function.prototype //true
Object.__proto__ === Function.__proto__//true
Object.prototype === Function.prototype.__proto__ // true
//因此
Function instanceof Object //true
Object instanceof Function //true
复制代码

函数a的原型:

所有的函数都继承自Object,函数的原型是Object的实例, 因为Function.__proto__.__proto__===Object.prototype为true,也可以用Function.prototype.isPrototypeOf(Object)为true判断。
是对象就可以增加属性,所以a.name挂在了函数上,那他有没有丢呢?由例子打印的第二个值可以看出来没丢。

是对象都可以增加属性,Array.__proto__.__proto__===Object.prototype为ture,Array.__proto__.__proto__.isPrototypeOf(Object)为true,所以Array和Function一样,也可以增加属性。感兴趣可自行测试。

误区2:this是函数局部作用域?

var name='hello'
function a(){  var name='world';  console.log(this.name)  
}
a();    //hello
复制代码

上例打印hello,不是world,说明this并不是函数的局部作用域。

误区3:this指向父级函数作用域?

var name='hello'
function a(){  console.log(this.name) 
}
function b(){ var name='world';    a();   
}
b();    //hello
复制代码

该例子打印的是hello,而不是world,说明this并不是父级函数作用域,而是调用上下文。

误区4:函数的this指向与调用该函数的地方this相同?

var name='hello';
function a(){   console.log(this.name)
}
var c={    name:'haha',    d: function(){ console.log(this.name); // haha a(); } 
}
c.d();    // haha  hello
复制代码

照理说,如果函数的this指向与调用该函数的地方this相同,那么两个都打印haha,然而事实却是,先打印haha,再打印hello,说明跟调用函数外部的this无关,可能有人有困惑,为什么会这样呢?我也不知道哈哈

相关文章:

java序列化的作用-这个挺有用的,不妨学学

http://bbs.tech.ccidnet.com/read.php?tid249048 最近在阅读Core J2EE Patterns 的时候发现例子里用于在各个层次里进行传输的TO(Data Transfer Object)都实现了java.io.Serializable接口,看到这些偶突然感到茅塞顿开~困扰了很久…

二分法典例:木棒切割问题

Input : 输入木棒根数n,要得到的等长木棒数量K,以及n根木棒的长度。 Output : 等长木棒的最大长度。 用二分法求解这道题,首先要找到以得到的等长木棒数量为因变量、等长木棒长度为自变量函数。 int getK(int l){//随着l增大,返…

对Android 开发者有益的 40 条优化建议(转)

下面是开始Android编程的好方法: 找一些与你想做事情类似的代码 调整它,尝试让它做你像做的事情 经历问题 使用StackOverflow解决问题对每个你像添加的特征重复上述过程。这种方法能够激励你,因为你在保持不断迭代,不经意中你学到…

英语语法总结--连词

连词 连词是一种虚词, 它不能独立担任句子成分而只起连接词与词,短语与短语以及句与句的作用。连词主要可分为两类:并列连词和从属连词。并列连词用来连接平行的词、词组和分 句。如:and, but, or, nor, so, therefore, yet, howe…

开放平台鉴权以及OAuth2.0介绍

OAuth 2.0 协议 OAuth是一个开发标准,允许用户授权第三方网站或应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的内容。OAuth 2.0不兼容1.0。协议的参与者 RO (resource owner): 资源所有者&#xf…

1044 Shopping in Mars

这题我写了两个二分函数。 BS借用的模板是找到第一个大于等于总价的商品下标,然后返回的是钻石价值和减去商品总价,通过遍历来得到最小的差值,注意遍历的最后一个数字的时候可能会返回负值,所以只有当返回值大于等于0才可以用来竞…

nodeJS之eventproxy源码解读

1.源码缩影 !(function (name, definition) { var hasDefine typeof define function, //检查上下文环境是否为AMD或CMD hasExports typeof module ! undefined && module.exports; //检查上下文环境是否为Node if (hasDefine) { define(definition); //AMD环境或CM…

解决phpmyadmin3.4空密码登录被禁止登陆的方法

很多时候我们在本机测试时会将root用户密码设置为空。因为我把php升级到了5.3.1,以前的phpmyadmin版本不能用了,就升级到phpMyAdmin 3.2.4版的时候,会遇到无法以空密码登录root用户的情况。怎么解决呢? 请参照如下步骤: 1、打开程…

CentOS安装新版RabbitMQ解决Erlang 19.3版本依赖

2019独角兽企业重金招聘Python工程师标准>>> 通过yum等软件仓库都可以直接安装RabbitMQ,但版本一般都较为保守。 RabbitMQ官网提供了新版的rpm包(http://www.rabbitmq.com/download.html),但是安装的时候会提示需要erl…

1048 Find Coins(二分法解法)

非常基础的二分法-寻找序列中是否存在某一条件的元素 的应用 AC代码 #include<cstdio> #include<iostream> #include<set> #include<vector> #include<map> #include<algorithm>using namespace std;const int SUP 100000000; const in…

关于chrome等浏览器不支持showModalDialog的解决方案

目前&#xff0c;新版本的chrome和opera、Firefox等浏览器已经不支持showModalDialog方法。 如果是没有接收返回值的&#xff0c;可以直接将window.showModalDialog改为window.open。 需要接收返回值的情况&#xff1a; 父页面设置&#xff1a; var uIdName; function chooseus…

Flex Javascript 交互实现代码

关键字&#xff1a;ExternalInterface所用类库&#xff1a;SWFObject/*** Flex调用Javascript函数* params functionName:String Javascript函数名称* params ...params Javascript函数参数* return 返回Javascript函数的return内容**/ExternalInterface.call(functionName:Str…

C#反射使用时注意BindingFlags的用法(转载)

最近刚刚开始用反射做项目&#xff0c;遇到一个小的知识点&#xff0c;记录一下。 c#反射查找方法时&#xff0c;默认只能查到public方法。如果想要查找private方法&#xff0c;需要设定BindingFlags. 即&#xff1a; BindingFlags.Public|BindingFlags.Instance 默认…

1126 Eulerian Path

主要考英语或者数学基础。 一幅连通图的奇点个数为0或2时才能够被一笔画。 连通图的判断用DFS来计数。 连通图0个奇点&#xff1a;Eulerian 连通图2个奇点&#xff1a;semi-Eulerian 非连通图/连通图其他数量的奇点&#xff1a;non-Eulerian AC代码 #include<cstdio&…

各种小的 dp (精)

Q~ 抛一枚硬币 n 次&#xff0c;每次可能是正面或者反面向上&#xff0c;求没有连续超过 k 次硬币向上的方案数 A &#xff1a; dp[ i ] 表示到 i 位置的方案数&#xff0c; 1 . 当 i < k 时&#xff0c; dp[i] dp[i-1]*2 2 . 当 i k 时&#xff0c; dp[i] dp[i-1]*2 - 1…

写给还在大学的兄弟姐妹

看到软件专业毕业生之一个月攻略 这篇文章之后&#xff0c;忽然想起了自己两个多月前找工作时的写的一篇文章&#xff0c;便拿出来与大家分享。这仅是个人的一些看法&#xff0c;不正确之处还请各位指出&#xff0c;有砖尽管拍。 基础很重要 许多企业招聘&#xff0c;要求大学…

grunt学习

1、http://javascript.ruanyifeng.com/tool/grunt.html Grunt&#xff1a;任务自动管理工具 2、转载于:https://www.cnblogs.com/king-bj/p/4322794.html

IP地址和MAC地址

MAC地址又称硬件地址&#xff0c;是MAC帧的头部&#xff0c;在数据链路层只能看见MAC地址。 IP地址是逻辑地址&#xff0c;是IP数据报的头部&#xff0c;路由器根据IP地址进行路由选择。 IP地址为4个字节32位&#xff0c;编制经历了3个历史阶段。 MAC地址为6个字节48位。

ie9下console不兼容的问题

最近在调整项目在ie9下的展示问题&#xff0c;发现在ie9下&#xff0c;js文件不执行&#xff0c;打开控制台才执行&#xff0c;原因是ie9不支持console&#xff0c;以下给出两种解决方案&#xff1a;1. 在webpack.prod.conf.js 中添加并修改js插件配置项&#xff08;我用的是we…

[转载] linux、Solaris下xdmcp远程桌面服务

原文链接 http://youlvconglin.blog.163.com/blog/static/52320420106243857254/ 使用图形界面远程登录linux和Solaris&#xff0c;首先要在服务端开启xdmcp服务&#xff0c;windows下使用xmanager连接 Ubuntu下则使用下默认也安装了该客户端&#xff0c;一次打开[应用程序]-[…

3.2.4 控制图层显示的范围

为了是地图更加简洁 和 减小地图负载 &#xff0c;达到分级显示某些图层的效果&#xff0c;应该为每一个图层设置 合理的 可见比例尺范围。1 begin2 3 aeMapMain.Layer[2].MaximumScale :500000;//最大可见比例尺 分母4 aeMapMain.Layer[2].MinimumScale :1000000;//最小可见比…

1103 Integer Factorization 需再做

本题是典型的DFS剪枝 我对DFS有了更深的认识&#xff1a;整个过程就是一片森林(根节点不唯一)的生长&#xff0c;到了界限就得到结果并返回或者得不到结果也返回&#xff0c;DFS的参数存放的是所有需要积累的变量。 提示&#xff1a; 1. 最外层的while或者for可以看成是一个…

POJ1001--Exponentiation(幂计算)翻译

Exponentiation幂计算Time Limit: 500MSMemory Limit: 10000KTotal Submissions: 141868Accepted: 34673 Description 描述 Problems involving the computation of exact values of very large magnitude and precision are common. 高精度、大数值的计算问题是很常见的&…

datatable无法设置横向滚动条(设置无效)

datatable设置横向滚动条无效 js如下&#xff1a; 页面如下&#xff1a; 设置 scrollx 属性为true时&#xff0c;还需在 table 添加 style"white-space: nowrap; "最终效果&#xff1a; 转载于:https://www.cnblogs.com/renzp/p/10069594.html

水晶报表导出数据并实现打印

要在里一个页面上进行操作 ReportDocument rdocument new ReportDocument(); //公用打印方法 ExportCrystalL ExCrystal new ExportCrystalL(); User u new User(); #region 加载页面 protected void Page_Load(object sender, EventArgs e) { if (!IsPostB…

1130 Infix Expression

考察&#xff1a;DFS进行中序遍历。 注意&#xff1a;给除了根节点以外的父节点加左右括号。 AC代码 #include<cstdio> #include<iostream> #include<set> #include<vector> #include<map> #include<algorithm> #include<cmath> …

学习笔记之vue根据权限动态添加路由

路由守卫判断 router.beforeEach((to, from, next) > {if (to.path /login) {sessionStorage.removeItem(user);}if (!user && to.path ! /login&&location.search ! ?validate) {next({ path: /login })} else {next()} }) 复制代码 点击登陆后&#xff…

javascript重置(base层)(。。。。不完整)

1、nextSibling浏览器兼容问题 <ul><li id"item1"></li><li id"item2"></li><li id"item3"></li> </ul> var item1document.getElementById("item1"); alert(item1.nextSibling.id);…

java myeclipse jar 导出问题

1.工程 jdk要和实际jdk最好一个版本;2.有外部导入的jar,导出时应用manifest&#xff0c;设置外部引用JAR。例如&#xff1a;Manifest-Version: 1.0 Sealed: true Class-Path: lib/log4j-1.2.8.jar lib/xercesImpl.jar Main-Class: com.unimoco.mmsplatform.handler.MMSMOCenter…

漫谈回溯(未完待续)

将不使用优化算法、直接用朴素算法来解决问题的做法称为暴力法。 回溯是带优化的穷举。 回溯是具有界限函数的深度优先搜索。