JavaScript closure: difference between call and apply as well as use them to create inheritance

原创 2016年08月29日 19:35:50

Resume

Today, in an interview, speaking of closure, the interviewer asked me about the difference between call() and apply(). And I didn’t use them before. After searching for a while, I found that we can implement completely a class with JavaScript. We can implement a constructor by using call() and apply(). I thought that we can only implement a class without any inheritance before. This passage will describe what I have found.


call()

Syntax:
function.call(thisArg, arg1, arg2, ...)


Suppose we have a function like this,

var lang = {'languages':['Python', 'Haskell', 'C++', 'Java']};
var favoriteLanguages = function(){
    for(var i = 0; i < this.languages.length; i++){
        console.log('My favorite languages is', this.languages[i]);
    }
}
favoriteLanguages.call(lang);

and it will print

My favorite languages is Python
My favorite languages is Haskell
My favorite languages is C++
My favorite languages is Java

on console.


So, consequently we can say that function.call() will apply arguments to function as local variable.


apply()

Syntax:
fun.apply(thisArg, [argsArray])



Actually it’s quite simular to call(). The only difference is we pass arguments call() while we pass an argument and a list of argument to apply().
Moreover, usually we pass this as the first argument to apply.
It’s all the same when we do:

var lang = {'languages':['Python', 'Haskell', 'C++', 'Java']};
var favoriteLanguages = function(){
    for(var i = 0; i < this.languages.length; i++){
        console.log('My favorite languages is', this.languages[i]);
    }
}
favoriteLanguages.applu(lang);//We changed here.



But when we try to do something different, there will be some differences.

var languages= {'prog_languages':['Python', 'Haskell', 'C++', 'Java'],'languages':['English', 'Français', '中文']};

var prog_l = function(){
    for(var i = 0; i < this.prog_languages.length; i++){
        console.log('I like', this.prog_languages[i], 'as a programming language.');
    }
}

var lang = function(){
    for(var i = 0; i < this.languages.length; i++){
        console.log('I like', this.languages[i], 'as a language.');
    }
}

var dispatch = function(method0, args0, method1, args1){
    method0.apply(args0);
    method1.apply(args1);
};

dispatch(lang,languages,prog_l,languages);

When we run codes above, it will show

I like English as a language.
I like Français as a language.
I like 中文 as a language.
I like Python as a programming language.
I like Haskell as a programming language.
I like C++ as a programming language.
I like Java as a programming language

in console.


It means that when we are not certain how many parameters we will pass, it’s better to use apply() than call(). Because apply() put the first argument into this and take the send argument which is a list as arguments applying to function.


Inheritance

Actually it’s a little bit like the object principle in most programming languages such as Java and C++.
Let’s see an example on mozilla.org.

function Product(name, price) {
    this.name = name;
    this.price = price;
    if (price < 0) {
        throw RangeError('Cannot create product ' + this.name + ' with a negative price');
    }
}

function Food(name, price) {
    Product.call(this, name, price);
    this.category = 'food';
}

function Toy(name, price) {
    Product.call(this, name, price);
    this.category = 'toy';
}

var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);

console.log(cheese.price);

When we run these codes, it will return 5 which is exactly the price of cheese.
But why?
When we instantiate Food, then we jump into the function Food(name, price), then we invoke the function Product.call(this, name, price) and pass this to Product(name, price). In Product(name, price), actually we are modifying Food, because we passed this in Product.call(this, name, price). So that this points to object Food. And we assign name and price to this(which is the reference of Food).
So, it’s the object Food which is being modified and finally we have name, price and category in Food.


Pretty like in Java, isn’t it?
In Java, we may write

class Product{
    protected String name;
    protected int price;
    public Product(String name, int price){
        this.name = name;
        this.price = price;
        if (price < 0) {
            throw new RangeError('Cannot create product ' + this.name + ' with a negative price'); //RangeError is not defined, because it's not important in this case.
        }
    }
}

and

class Food extends Product{
    protected String category = "food";
    public Food(String name, int price){
        super(name, price);
    }
}

References

版权声明:本文章禁止商业使用,非商用转载必须注明出处和作者。作者保留一切权利。 举报

相关文章推荐

Michael Kors Laukut dope need and as well lung cancer: connection between a suit operate education

cannabis employ with united states: outcomes of in a situation decrease survey. us citizen Thoracic ...

how to use a SQLite database in a standalone program with an HTML interface and VBScript as the programming language

This article describes how to use a SQLite database in a standalone program with an HTML interface a...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

Difference Between CALL TRANSACTION and SESSION METHOD

for this subject, I got 2 articles for reference: 1. http://wiki.sdn.sap.com/wiki/display/ABAP/Diff...

as3.0 Function.apply()与Function.call()方法简介

Function:函数是可在 ActionScript 中调用的基本代码单位。 ActionScript 中用户定义的函数和内置函数都由 Function 对象来表示,该对象是 Function 类的...

Difference between prototype and this in JavaScript

When I’m studying JavaScript, I got a little bit confused while I first time look at function.protot...

A Guide to Blocks & Grand Central Dispatch (and the Cocoa API's making use of them)

Intro As you may or may not know I recently did a talk at the Des Moines Cocoaheads in which I revie...

Swift Optionals: When to use if let, when ? and !, when as? and as

原文地址:http://www.touch-code-magazine.com/swift-optionals-use-let/1. 可选类型是什么?回忆你知道的普通的数据类型,就像你在的Object...

How to use json with as3corelib in flex( JSON )

How to use json with as3corelib in flex(  JSON ) 摘要:本文主要介绍as3corelib如何在flex中使用,以及如何在flex中使用json...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)