call定义

语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 
定义:调用一个对象的一个方法,以另一个对象替换当前对象。 
说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。 
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

又遇见了各种专业名词了吧,没有经过长期的文档摧残是无法快速掌握一个方法的精髓的,一起做几个小实验吧

var myName = 'goudan';

var myAge = 13;

function showMsg(msg){

  return msg + ''.toLowerCase();

}

showName(myName); // 'goudan'

这段代码很容易就能看懂,在实际开发工作中,我们会处理不同的数据集合,这时候var单一变量已经无法满足胃口,需要通过json的形式来存储数据

var person = {

  name:"kyogre",

  age:13,

  hobby:"coding"

}

var newPerson  ={

  name:'dachui',

  age:99,

  hobby:'eat'

}

function showMsg(msg){

  return msg + ''.toLowerCase();

}

showMsg(person.name) // 'kyogre'

showMsg(newPerson.name) // 'dachui'

存储数据的方式发生了改变,但是我们处理数据的方式还是那么。。。古老,如果业务复杂一点

function format(msg){

  return msg+''.toLowerCase();

}

function show(msg){

  return '信息的内容是:'+ format(msg);

}

show(person.name) // '信息内容是:kyogre'

show(newPerson.name) // '信息内容是:dachui'

显示的传递上下文对象 (穿参)使得业务越来越复杂,这种叠加会让开发变得冗余和难以解读,bug和闭包横飞

那我们看看通过this如何清晰解决问题

通常this不会指向函数自身,而是调用函数的对象主体。当然,我们可以强制让function自身成为对象主体,这个以后咱们讨论; json本身就是对象,我们是否可以这样:

var person = {

  name:"kyogre",

  age:13,

  hobby:"coding"

}

var newPerson  ={

  name:'dachui',

  age:99,

  hobby:'eat'

}

function format(){

  return this.name+''.toLowerCase();

}

问题来了,不让穿参这个format中的this指向谁呢? 指向调用format的对象本身,可是调用主体并不明确,可能是person也可能是newPerson,这时回过头看看call的定义吧:调用一个对象的一个方法,以另一个对象替换当前对象。 将函数内部执行上下文对象由原始对象替换为指定对象

var name = '我叫window';    //全局变量 非严格模式下都为 window的属性   window.name;

function format(){

  return this.name+''.toLowerCase();

}

format(); //'我叫window';

不要惊慌,本身他就是这样window会作为调用顶级作用域链函数的对象主体;这里的this默认为 window, 用person对象代替window这个默认this主体去执行format会怎么样呢

format.call(person);

// kyogre

format.call(newPerson);

// dachui

function show(){

  return '信息的内容是:'+ format.call(this);

}

show.call(person); // 信息的内容是:kyogre

感觉自己了解了this和call的小明,已经肆无忌惮的笑了起来,这样他就可以从繁重的回调与参数传递中解脱了,并且能够实现方法的初级模块化。可是事情并没有这么简单。。。知道的越多,不知道的就越多 ;-)


下面可以用call做一些平常的操作

function isArray(object){

  return Object.prototype.toString.call(object) == '[object Array]';

}// 借用Object原型上的toString方法来验证下对象是否是数组?

function accumulation(){

  return [].reduce.call(arguments,(a,b)=>{return a+b}

}//让不能使用数组方法的arguments类数组集合使用借用数组的reduce方法

return Array.prototype.forEach.call($$('*'),(item)=>{item.style.border = '1px solid red';}

//把类数组节点集合通过call借用数组的forEach方法实现。。。你自己在控制台用一下就知道,O(∩_∩)O~

真正决定this指向谁的并不一定是能看的见的对象,很多情况this会被隐性改变,this没有谁调用就指向谁那么简单; 如果想要深入理解,我们下次有机会谈一下执行上下文和词法作用域吧。。。。

javascript中call与this的初见的更多相关文章

  1. JavaScript从初见到热恋之深度讨论JavaScript中的面向对象。

    JavaScript中的面向对象.面向对象的三个基本特征:封装.继承.多态. 1.封装 js的封装如下 定义Person类 function Person(name,age,sex) { this.n ...

  2. 私人定制javascript中函数小知识点

    函数的定义 首先在javascript中,函数就是对象,程序可以随意操控它们.比如,可以给它们设置属性,甚至调用它们的方法.函数使用function关键字来定义.它既可以用在函数定义表达式,也可以用在 ...

  3. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  4. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  5. JavaScript 中的数据类型

    Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...

  6. javascript中的操作符详解1

    好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...

  7. 掌握javascript中的最基础数据结构-----数组

    这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...

  8. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

  9. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

随机推荐

  1. 1014 Waiting in Line (30分)

    1014 Waiting in Line (30分)   Suppose a bank has N windows open for service. There is a yellow line i ...

  2. Spring Boot + MyBatis + PostgreSql

    Maven构建项目 1.访问http://start.spring.io/ 2.选择构建工具Maven Project.Spring Boot版本1.3.6以及一些工程基本信息,点击“Switch t ...

  3. 使用TortoiseGit处理代码冲突

    使用TortoiseGit处理代码冲突  https://www.cnblogs.com/jason-beijing/p/5718190.html 场景一  user0 有新提交 user1 没有pu ...

  4. java 获取web登录者的ip地址

    /** * 获取访问用户的客户端IP(适用于公网与局域网). */ public static final String getIpAddr(final HttpServletRequest requ ...

  5. Azure DNS-

    先看什么是DNS,通常来讲,DNS是将域名解析成IP的服务,例如www.azure.cn对应的IP地址是139.217.8.104 使用域名访问有如下好处: 1. 好记,使用特定的字母组合,代替ip地 ...

  6. ActiveMQ--模式(队列模式/主题模式)

    两种模式:队列模式/主题模式 pom.xml <dependency> <groupId>org.apache.activemq</groupId> <art ...

  7. 「ZJOI2007」捉迷藏

    题目描述 给出一棵\(N\)个有色(黑白,黑色对应关灯,白色对应开灯)节点的树以及\(M\)次操作,每次操作将改变一个节点的颜色或者求出树上最远的两个白点距离 基本思路 \(60pts\)做法 这道题 ...

  8. 使用C语言实现文件的操作

    #include <stdio.h> int main(int argc, char* argv[]) { // 创建文件类型 FILE* file; char buf[1024] = { ...

  9. sqlserver 取数据常用

    sqlDataReader: public SqlDataReader GetAuth_CourtListByAuth(int autIntNo) { // Create Instance of Co ...

  10. 常用的UI控件

    关于本文:作为一名iOS软件工程师,熟练规范的使用常用的UI控件是必备的基础技能. 指示器(UIActivityIndicatorView)----转动的等待小菊花 提醒对话框(UIAlertView ...