js thiskeyword
相信大家都接触过this了,那么 this究竟是什么意思呢?看其字面意思就是个代词。指代其它的一些东西。
那么我们在程序其中,事实上也是一样。this也是个代词。
比方我们在java其中,this的keyword是指代当前class 的本身。不管this身处何处,this都指向当前class,它的作用域是作用域整个class的。
只是我们今天不是讲后台。我们的重点是讲js。那么js中的thiskeyword的作用域是怎么样的呢?和java有什么差别呢?
1,第一种情况
var person= function(){
this.name = "spring";
this.age = 25;
alert(this); //output: window
}
这段代码的thiskeyword指向的是全局window对象.
2,另外一种情况
var person= function(){
this.name = "spring";
this.age = 25;
console.log(this); //output: person本身
}
new person(); //解释:实例化this指代person对象
那么如上所看到的,实例化该person对象之后。this指向的是当前person的本身。
3。第三种情况
var person = {
name:"spring",
age: 25,
eat: function(){
alert(this.name+"正在吃饭"); //output: spring 正在吃饭
}
}
person.eat();//解释:this指代当前person对象
4。第四种情况:
var person = {
name:"spring",
age: 25,
sex:{
male:"男",
getMale: function(){
console.log(this); //output: sex object
}
}
};
person.sex.getMale(); //解释:this指代sex object
------------------------------------------------------------------------------------------------------------
好了写到这里。各位看明确了没有?请注意红色部分字体。
new person(); //this指代person对象
person.eat();//this指代当前person对象
person.sex.getMale(); //this指代sex对象
依据这个规律,我们能够得出一个结论:
谁调用的this就指代谁。
5,第五种情况:回调函数
function test(){
var person = {
name:"spring",
age: 25,
getAge: function(callback){
console.log(this); //output: person object
callback(this.age);
}
}
alert(this); //output: test object
person.getAge(function(age){
alert(age);//output: 25
//xxx
alert(this);//output: window object
});
}
new test();
注意看上面回调函数里面的this(// xxx以下那一行),却指向了window全局对象,哎。
怎么是这样。为什么不是person对象呢?为什么不是test对象呢?
那么按照我们上面的结论,谁调用指向谁。那么我们看是谁调用的?
噢,找到了,声明了一个匿名函数当做參数传递给了getAge(callback)方法。然后运行了callback(this.age);
那么我们又想一下,这个匿名函数又是谁呢?好像谁都不属于,那么该匿名函数就是指向window对象啦。
soga,原来是这样。似乎有点点懂了。
结论:回调函数的时候,this的上下文发生了变化,也就是this的指针发生了变化。
只是我们一般会这样做:
alert(this); //output: test object
var self = this; //self 保存this作用域
person.getAge(function(age){
alert(age);//output: 25
alert(this);//output: window object
alert(self);//output: test object;
});
噢。原来这样用self变量去储存当前this(也就是test)对象。
6.第六种情况prototype
//编写一个string的insert method
String.prototype.insert = function(){
console.log(this); //output > String {0: "1", 1: "2", 2: "3", 3: "4", 4: "5", 5: "6", length: 6, insert: function}
//这里this代表的是String.prototype > object对象
console.log(this.toString()); //output string "123456"
}
test();
function test(){
var str = "123456";
str.insert(); //调用insert method
}
然后我们再看另外一段代码:
function Person(name){
console.log(this);//output > Person
this.name = name;
}
Person.prototype.getName = function(){
console.log(this);//output > Person
return this.name;
};
var person = new Person("spring"); //实例化this代表自身
person.getName(); // output > spring
上面这种写法等同于以下这种写法:
function Person(name){
this.name = name;
}
Person.prototype = {
getName: function(){
console.log(this);//output > Person
return this.name;
}
};
7.第七种情况call、apply
function base(){
this.add = function(){
console.log(this);//output > test {add: function} ,this指针发生了变化
}
}
function test(){
console.log(this);//output > test {}
base.call(this); //call方法会把这个base中的this对象用这个this(也就是test对象)取代,
//取代之后,自然base对象中的this.add 方法就变成了test的方法属性了
//call方法把别人的东西变成自己的。 other.call(yourself)。yourself对象会取代other中的this对象
console.log(this) //output > test {add: function}
}
var result = new test();
console.log(result);//output > test {add: function}
result.add();//调用,调用之后,发现this的指针发生了变化。
this不再是base对象而是变成了test对象了。
call带參数的情况:
function base(d1,d2){
alert(d1+d2); //output > 123456
this.add = function(){
console.log(this);//output > test {add: function}
}
}
function test(){
base.call(this,"123","456");//多个參数用逗号隔开:"123","456","789"……
}
var result = new test();
apply method:
call 和apply的差别就是參数类型不同
function base(d1,d2){ //非常惊奇的发现,本来传给我的參数是一个数组呀。按道理来说我应该接收的是一个数组嘛,但是却被拆分成两个对象。
alert(d1+d2); //output > 123456
this.add = function(){
console.log(this);//output > test {add: function}
}
}
function test(){
base.apply(this,["123","456"]); //參数是数组:["123","456","789"……]
}
var result = new test();
改动下变成:
function base(d1,d2){
alert(d1+d2);//output > 123456
this.add = function(data){
alert(data);//output > ADD
}
}
function test(){
}
var result = new test();
base.apply(result,["123","456"]);
result.add("ADD")
js thiskeyword的更多相关文章
- JS学习笔记-OO疑问之封装
封装是面向对象的基础,今天所要学习的匿名函数与闭包就是为了实现JS的面向对象封装.封装实现.封装变量,提高数据.系统安全性,封装正是面向对象的基础. 一.匿名函数 即没有名字的函数,其创建方式为 fu ...
- js面对对象编程(二):属性和闭包
上篇博客中解说了一些js对象的基本概念和使用方法.这篇博客解说一下js属性方面的:公有属性.私有属性,特权方法. 假设学过java.公有属性.私有属性,特权方法(即能够訪问和设置私有属性的方法)一定非 ...
- js:对象的创建(为prototype做铺垫)
/** *在js中并不存在类,所以能够直接通过Object来创建对象,可是使用这样的方式创建有一 *弊端:因为没有类的约束,无法实现对象的反复利用,而且没有一种规范约定,在操作时easy带来问题. ...
- js中的函数function
js的function对象在调用过程中具有一个arguments的属性,它是由脚本解释器创建的(这也是arguments创建的唯一方式). arguments属性能够看作是一个Array对象,它有le ...
- js面试题--js的继承
js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明白的继承机制.而是通过模仿实现的.依据js语言的本身的特性,js实现继承有下面通用的几种方式 1.使用对象冒充实现继承(该种实 ...
- Vue.js 和 MVVM 小细节
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...
- js学习笔记:操作iframe
iframe可以说是比较老得话题了,而且网上也基本上在说少用iframe,其原因大致为:堵塞页面加载.安全问题.兼容性问题.搜索引擎抓取不到等等,不过相对于这些缺点,iframe的优点更牛,跨域请求. ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- JS调用Android、Ios原生控件
在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...
随机推荐
- 使用JWT实现Token认证
为什么使用JWT? 随着技术的发展,分布式web应用的普及,通过session管理用户登录状态成本越来越高,因此慢慢发展成为token的方式做登录身份校验,然后通过token去取redis中的缓存的用 ...
- C语言扩展题
1.使用cmake来创建c语言工程 2.使用gcc来编译源代码 3.下载redis,并且编译运行redis(注:redis目前是c语言编写的,而且是主要是linux平台,在windows平台编译比较麻 ...
- JS和CS互访【后台前台代码调用JavaScript变量以及JavaScript调用代码变量】
原文发布时间为:2008-10-13 -- 来源于本人的百度文章 [由搬家工具导入] .如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3.如何在C#中访问Ja ...
- vue.js源码学习分享(二)
/** * Check if value is primitive//检查该值是否是个原始值 */ function isPrimitive (value) { return typeof value ...
- WebRTC 介绍 (转)
google开源了WebRTC项目,网址是:http://code.google.com/p/webrtc/. WebRTC实现了基于网页的视频会议,标准是WHATWG 协议,目的是通过浏览器提供简单 ...
- AC日记——联合权值 洛谷 P1351
题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...
- [转载][FPGA]Quartus代码保护-生成网表文件
0. 简介 当项目过程中,不想给甲方源码时,该如何?我们可以用网表文件qxp或者vqm对资源进行保护. 下面讲解这两个文件的具体生成步骤: 1. 基本概念 QuartusII的qxp文件为Quartu ...
- Widows下利用OpenSSL生成证书
1.下载OpenSSL的windows版本 32位:openssl-1.0.2a-i386-win32.zip 64位:openssl-1.0.2a-x64_86-win64.zip 下载之后解压即可 ...
- 线程池之ThreadPoolExecutor线程池源码分析笔记
1.线程池的作用 一方面当执行大量异步任务时候线程池能够提供较好的性能,在不使用线程池的时候,每当需要执行异步任务时候是直接 new 一线程进行运行,而线程的创建和销毁是需要开销的.使用线程池时候,线 ...
- trick点
1.问题里有取模操作的时候,最后输出(ans+mod)%mod 2.涉及到输出实数0的时候要特判输出的会不是是-0.000000(因为0.00乘一个负的浮点数结果是-0.000000,乘一个正的浮点数 ...