• 1.改变this指向
  • 2.Function.prototype.bind
  • 3.借用其他对象方法
    • 1.借用实现继承
    • 2.实现恶心的
      • Array.prototype.push.call
      • Array.prototype.join.call
      • Array.prototype.slice.call
      • Object.prototype.toString.call

1.改变this指向

var obj1 = {
name:"Bob marley"
};
var obj2 = {
name:"Bob Dylan"
};
var name = "David Bowie";
var getName = function(){
console.log(this.name);
}
getName(); //输出undefined
getName.call(obj1); //输出Bob marley
getName.call(obj2); //输出Bob Dylan

在实际开发中,经常会遇到this指向被不经意改变的场景:例如:

document.getElementById('div1').onclick=function(){
alert(this.id); //输出div1
var func = function(){
alert(this.id); //输出undefined
}
func();
};

使用call来修复func函数内的this,使其指向div

document.getElementById('div1').onclick=function(){
alert(this.id);
var func = function(){
alert(this.id);
}
func.call(this);
};
再如: var name = "SmarTom";
var func = function(){
console.log(this.name);
}
func();

使用call来修复func函数内的this,使其指向div 再如:

var obj ={
name : "SmarTom"
}
var func = function(){
console.log(this.name);
}
func.call(obj);

2.Function.prototype.bind

大部分浏览器都实现了内置的Function.prototype.bind,用来指定函数内部的this指向 即使没有原生的Function.prototype.bind实现,也可以模拟一下,例如:

//在一些浏览器中可以忽略 bind函数
Function.prototype.bind = function(context){
var _self = this;
return function(){
return _self.apply(context,arguments);
}
}
var obj = {
name :"SmarTom"
}
var func = function(){
console.log(this.name);
}.bind(obj); //进行绑定
func();
 

3.借用其他对象的方法【实现继承】

1.借用实现继承

var A = function(name){                 //父类 A
this.name = name;
}
var B = function(){ //子类 B 继承父类A
A.apply(this,arguments);
}
B.prototype.getName = function(){ //B方法
return this.name;
}
var b = new B('asdfasdfasdf');
console.log(b.getName());

2.实现

Array.prototype.push.call
Array.prototype.join.call
Array.prototype.slice.call
Object.prototype.toString.call() 1. Array.prototype.push.call
Array.prototype.push.call(obj,arguments)
相当于var html = []; html.push(那一大堆)
<script type="text/javascript">
(function () {
var customService = function () { };
customService.prototype = {
open: function () {
contents: this._getHtml(),
},
close: function () { },
_getHtml: function () {
var html = [];
Array.prototype.push.call(html,
'<div class=\"content\">',
'<div>1、</div>',
'<div>2、<\/div>',
'<div>3、<\/div>',
'<div>4、<\/div>',
'<\/div>'
);
return html.join('');
}
};
window.CustomService = new customService();
})();
</script> 2.Array.prototype.join.call
//arguments就相当于一个对象数组
Array.prototype.join.call(arguments,',')
就类似于window.join方法.apply,call不会改变scope,可参考finally里的内容
<script type="text/javascript">
var join = function () {
for (var i = 0, b = ''; i < this.length ; i ++) {
if (i) b+= arguments[0];
b += this[i];
}
return b;
}; var show = function () {
//new Array(arguments)).join('_');
//try
try {
alert(
Array.apply(null, arguments).join('_')
);
return join.call(arguments, '-'); //Array.prototype.join就类似于window.join方法.apply,call不会改变scope,可参考finally里的内容
} finally {
var func = function () {
alert(a);
}; void function () {
var a = 1;
try {
func.call(this);
} catch (exp) {
alert(exp.message);
}
}();
}
}; alert(show(1, 2, 3, 5));
</script> 3.Array.prototype.slice.call
var a={length:2,0:'first',1:'second'};
Array.prototype.slice.call(a);// ["first", "second"]
var a={length:2};
Array.prototype.slice.call(a);// [undefined, undefined]
可能刚开始学习js的童鞋并不是很能理解这句为什么能实现这样的功能。
比如我就是一个,所以,来探究一下。
首先,slice有两个用法,一个是String.slice,一个是Array.slice,
第一个返回的是字符串,第二个返回的是数组,这里我们看第2个。
Array.prototype.slice.call(arguments)能够将arguments转成数组,那么就是arguments.toArray().slice();
到这里,是不是就可以说Array.prototype.slice.call(arguments)的过程就是先将传入进来的第一个参数转为数组,再调用slice? 4.Object.prototype.toString.call
使用Object.prototype上的原生toString()方法判断数据类型,使用方法如下: Object.prototype.toString.call(value) 1.判断基本类型: Object.prototype.toString.call(null);//”[object Null]”
Object.prototype.toString.call(undefined);//”[object Undefined]”
Object.prototype.toString.call(“abc”);//”[object String]”
Object.prototype.toString.call(123);//”[object Number]”
Object.prototype.toString.call(true);//”[object Boolean]”
2.判断原生引用类型: 函数类型
Function fn(){console.log(“test”);}
Object.prototype.toString.call(fn);//”[object Function]”
日期类型
var date = new Date();
Object.prototype.toString.call(date);//”[object Date]”
数组类型
var arr = [1,2,3];
Object.prototype.toString.call(arr);//”[object Array]”
正则表达式
var reg = /[hbc]at/gi;
Object.prototype.toString.call(arr);//”[object Array]”
自定义类型
function Person(name, age) {
this.name = name;
this.age = age;
}
var person = new Person("Rose", 18);
Object.prototype.toString.call(arr); //”[object Object]”
很明显这种方法不能准确判断person是Person类的实例,而只能用instanceof 操作符来进行判断,如下所示:
console.log(person instanceof Person);//输出结果为true
3.判断原生JSON对象: var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON);
console.log(isNativeJSON);//输出结果为”[object JSON]”说明JSON是原生的,否则不是; 注意:Object.prototype.toString()本身是允许被修改的,而我们目前所讨论的关于
Object.prototype.toString()这个方法的应用都是假设toString()方法未被修改为前提的。

《JavaScript设计模式与开发》笔记 3.call和apply的更多相关文章

  1. JavaScript设计模式与开发实践(二)——apply&&call

    call和apply的用途 改变this指向 先看个例子: var obj1 = { name: 'sven' }; var obj2 = { name: 'anne' }; window.name ...

  2. 《JavaScript设计模式与开发实践》读书笔记-基础知识

    笔记内容多摘录自<JavaScript设计模式与开发实践>(曾探著),侵删. 面向对象的JavaScript 1. 动态需要类型和鸭子类型 鸭子类型 如果它走起路来像鸭子,叫起来也是鸭子, ...

  3. JavaScript设计模式与开发实践——读书笔记1.高阶函数(上)

    说来惭愧,4个多月未更新了.4月份以后就开始忙起来了,论文.毕设.毕业旅行等七七八八的事情占据了很多时间,毕业之后开始忙碌的工作,这期间一直想写博客,但是一直没能静下心写.这段时间在看<Java ...

  4. 《Javascript设计模式与开发实践》--读书笔记

    第2章 this call apply bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用. bind( ...

  5. 《javascript设计模式与开发实践》--- (单一职责原则)

    看的这本书叫<JavaScript设计模式与开发实践> 先规划一下看书的顺序,基础知识我已经大概的浏览了一遍了,没有留下笔记,以后有时间还会补上.本来打算顺着看的.但是我感觉我很难短时间内 ...

  6. 《JavaScript设计模式与开发实践》整理

    最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...

  7. JavaScript设计模式与开发实践 - 观察者模式

    概述 观察者模式又叫发布 - 订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个目标对象(为了方便理解,以下将观察者对象叫做订阅者,将目标对象叫做 ...

  8. JavaScript设计模式与开发实践 - 策略模式

    引言 本文摘自<JavaScript设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...

  9. JavaScript设计模式与开发实践 - 单例模式

    引言 本文摘自<JavaScript设计模式与开发实践> 在传统开发工程师眼里,单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返 ...

  10. 《JavaScript设计模式》读书笔记——灵活的语言

    最近在读JavaScript设计模式这本书,准备搞一个系列来记录所学所想,其实主要原因是方便以后查阅. 第一章主要介绍了JS函数的不同定义与使用方法,用自己的方法去模拟类也是它的独有魅力所在. 首先, ...

随机推荐

  1. chrome插件 - Manifest文件中的 background

    在Manifest中指定background域可以使扩展常驻后台. background可以包含三种属性,分别是scripts.page和persistent. 如果指定了scripts属性,则Chr ...

  2. ORACLE函数、连接查询、约束

    *ORDER BY 子句在SELECT语句的结尾. 使用外连接可以查询不满足连接条件的数据 with字句 字符函数lower upper initcap concat substr length in ...

  3. Python之路PythonNet,第一篇,网络1

    pythonnet   网络1 ARPAnet(互联网雏形)--->  民用 ISO(国际标准化组织)--->网络体系结构标准 OSI模型 OSI : 网络信息传输比较复杂需要很多功能协同 ...

  4. tflearn weights获取与存储

    参考: http://tflearn.org/examples/

  5. 一台机器上安装两个tomcat

    1.使用压缩版的tomcat不能使用安装版的.  2.第一个tomcat的配置不变.  3.增加环境变量CATALINA_HOME2,值为新的tomcat的地址:增加环境变量CATALINA_BASE ...

  6. 《DSP using MATLAB》Problem 6.23

    代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output In ...

  7. 利用cookie存放模糊查询的信息

    将前台传入后台的查询条件,存放到cookie中,并加入响应对象中,将该查询条件存放入浏览器端.(会话cookie,存放在浏览器的内存中,浏览器关闭,cookie消失.[不设置路径,和生命周期]) 注意 ...

  8. Eclipse和Intel idea的常用技巧

    使用Eclipse的几个必须掌握的快捷方式   “工若善其事,必先利其器”,感谢Eclipse,她 使我们阅读一个大工程的代码更加容易,在阅读的过程中,我发现掌握几个Eclipse的快捷键会使阅读体验 ...

  9. oracle使用一条语句批量插入多条数据

    例如我有一个test表 create table (stuid int,name varchar(20); 插入多条数据,注意不能直接使用insert into test values(1,'a'), ...

  10. linux之nagios安装教程

    我的系统环境是centos7,其它系统应该也差不多,只是有几条命令可能需要换种写法 下面是我用到的命令 363 yum install -y gcc gcc-c++ httpd php php-gd ...