GVKun编程网logo

JavaScrip Arrow Functions and This

25

本篇文章给大家谈谈JavaScripArrowFunctionsandThis,同时本文还将给你拓展CallingFlex/ActionscriptfunctionsfromJavascript、Fu

本篇文章给大家谈谈JavaScrip Arrow Functions and This,同时本文还将给你拓展Calling Flex / Actionscript functions from Javascript、Function Definition, This and Bind in JavaScript、function, new function, new Function之间的区别_javascript技巧、functional继承模式 摘自javascript:the good parts_javascript技巧等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

JavaScrip Arrow Functions and This

JavaScrip Arrow Functions and This

我正在尝试ES6,并希望像这样在我的函数中包含一个属性

var person = {  name: "jason",  shout: () => console.log("my name is ", this.name)}person.shout() // Should print out my name is jason

但是,当我运行此代码控制台时,仅显示log my name is。我究竟做错了什么?

答案1

小编典典

简短的答案:this指向最接近的边界this-所提供的代码this位于封闭范围内。

更长的答案:箭头功能 this 创建它们时将其绑定 没有thisarguments或结合其它特殊名字都正在创建对象时的名称this是在封闭的范围内,没有找到person对象。您可以通过移动声明来更清楚地看到这一点:

var person = {  name: "Jason"};person.shout = () => console.log("Hi, my name is", this);

并且在翻译成ES5中箭头语法的模糊近似时更加清晰:

var person = {  name: "Jason"};var shout = function() {  console.log("Hi, my name is", this.name);}.bind(this);person.shout = shout;

在这两种情况下,this(对于shout函数)都指向与其中person定义的作用域相同的函数,而不是将函数添加到person对象时附加的新作用域。

不能
使箭头函数那样工作,但是,正如@kamituel在他的答案中指出的那样,您可以利用ES6中较短的方法声明模式来节省相似的空间:

var person = {  name: "Jason",  // ES6 "method" declaration - leave off the ":" and the "function"  shout() {    console.log("Hi, my name is", this.name);  }};

Calling Flex / Actionscript functions from Javascript

Calling Flex / Actionscript functions from Javascript


Nowadays I am working with Flex projects,that runs on Lotus Notes platform,which consumes data from Lotus Notes backend. Since there is no remote services like BlazeDS to connect to Notes server,am Now greatly dependant on HTTPService and Javascript. Calling a javascript function from Flex is quite easy. Just use the ExternalInterface API. For those who don’t kNow the way,this is how it is getting called.

In AS3

if(ExternalInterface.available){
ExternalInterface.call(“openNotes”,parameter);
}

In Javascript

function openNotes(notesUrl){
window.open(notesUrl,”,‘width=1000,height=600′);
}

It is quite easy. But what if you need to call the reverse. ie,calling actionscript function from javascript. We can use the sameExternalInterface api for achieve this. There is a method calledaddCallback,available in ExternalInterface. addCallback method registers an ActionScript method as callable from the container. After a successful invocation of addCallBack(),the registered function in the player can be called by JavaScript or ActiveX code in the container. The first parameter is the name by which the container can invoke the function and the second parameter is the function closure to invoke. Below is the step-by-step configuration:

Step 1 : Register the call back from actionscript. For eg,call the below method in the creationComplete or initialize event of the component.

private function createCallBack(event:Event):void{
ExternalInterface.addCallback(“updateNotes”,getNotes);
}

private function getNotes():void{
//do whatever you want after getting the hold
}

Step 2 : Create logic in javascript to invoke the AS3 function.

//Javascript
function updateFlex(){
appName.updateNotes();
}

The appName is the name and id of the embedded swf object in the HTML. Like below :

That’s it. Now you can call the updateFlex javascript method from your HTML and it will invoke the AS3 callback function. Enjoy Coding guys. Flex Your Life. Cheers. :)




Reference:

http://deviltechie.wordpress.com/2012/05/08/calling-flex-actionscript-functions-from-javascript/

Function Definition, This and Bind in JavaScript

Function Definition, This and Bind in JavaScript

I thought I know the Function definition, execution context and the behavior of this in JavaScript. However, I realized that actually I don''t or the knowlege is still not firmly grounded in my mind when I wrote some code similar to below snippet but have no instinct of the error.

var TestObj = {
    a: function() {
        console.log(''A'');
    },
    b: function() {
        console.log(''B'');
        this.a();
    }
};

TestObj.b();

var c = TestObj.b;
c();

The result will be as below, right?

B
A
B
A

You might suspiciously answer No but If your instint doesnot tell you that and why, then you don''t know JavasScript well either like me. The result actually is:

B
A
B
TypeError: Object [object global] has no method ''a''

It is a little bit awkward or counterintuitive at first glance but it''s JavaScript. It''s the feature and amazing part. Let''s break it down piece by piece and see why.

Function definition

The TestObj includes two methods. The Function definition there actually creates two anonymous functions and then the references to the functions are assigned to the properties a and b. Those two functions are not owned by TestObj and just referred by the two properties of TestObj. This is the most important part causes the confusion. Hence, above code has not much difference than below except now we assign a name B for one of the function:

function B() {
    console.log(''B'');
    this.a();
};

var TestObj = {
    a: function() {
        console.log(''A'');
    },
    b: B
};

this

In ECMA-262 edition 5.1:

10.4.3 Entering Function Code
The following steps are performed when control enters the execution context for function code contained in
function object F, a caller provided thisArg, and a caller provided argumentsList:

  1. If the function code is strict code, set the ThisBinding to thisArg.
  2. Else if thisArg is null or undefined, set the ThisBinding to the global object.
  3. Else if Type(thisArg) is not Object, set the ThisBinding to ToObject(thisArg).
  4. Else set the ThisBinding to thisArg.
    ...

this is a special keyword refers to the binding object in the current execution context of the Function.

Once we invoke the Function through Object method, the this inside the Function body actually has been set to the TestObj instance. Hence, TestObj.b() logs B and A consecutively because this.a exists as a property of TestObj.

However, below statements mean differently.

var c = TestObj.b;
c();

Actually, variable c is just another reference pointing to Function B. Hence c() is same as B(). When directly invoking Function B, the this is bound to global object. Because there is no a defined in the global object, error occurs.

How to set a particular object as this to function

It''s commonly known that call and apply method can be called on the Function object providing a specific object as this, say:

var c = TestObj.b;
c.call(TestObj);

The result is desirable. However, this approach invokes the Function immediately. This is normally not the case that a Function has to be assigned to a Reference and passed around which is meant to be executed dynamically, like:

function dynamic(fn) {
  fn();
}

dynamic(TestObj.b);

In this case, we should not use fn.call(TestObj) or fn.apply(TestObj) because it''s a generic Function which should have no knowledge on the Function passed in. Hence, above is not working.

There is still another lifesaver though. The bind method of Function. This method can take the passed in Object like what call or apply does, but it returns a new Function whose this binding is set to the Object passed in. So, above code can be revised as:

function dynamic(fn) {
  fn();
}

dynamic(TestObj.b.bind(TestObj));

It''s fun, isn''t it?

[Edited on 2013/06/17]: Today, I saw another case which maybe confusing too.

var length = 3;

function logLength() {
  console.log(this.length);
}

var TestObj = {
    length: 2,
    b: logLength,
    c: function() {
        (function(fn) {
            arguments[0]();
        })(logLength);
    }
};

TestObj.b();
TestObj.c();

What do you think the console should log? Will it be 2 and 3? Actually, the result is 2 and 1. Because the TestObj.c() actually is calling the function logLength on the arguments Object, and then the this.length is referring to its own length, which is 1.

More fun, right?

function, new function, new Function之间的区别_javascript技巧

function, new function, new Function之间的区别_javascript技巧

函数是JavaScript中很重要的一个语言元素,并且提供了一个function关键字和内置对象Function,下面是其可能的用法和它们之间的关系。

    使用方法一: 

复制代码 代码如下:

 var foo01 = function() //or fun01 = function() 
 { 
     var temp = 100; 
     this.temp = 200; 
     return temp + this.temp; 
 } 

 alert(typeof(foo01)); 
 alert(foo01()); 
   运行结果:
 function
 300    最普通的function使用方式,定一个JavaScript函数。两种写法表现出来的运行效果完全相同,唯一的却别是后一种写法有较高的初始化优先级。在大扩号内的变量作用域中,this指代foo01的所有者,即window对象。

    使用方法二: 
 
复制代码 代码如下:

var foo02 = new function() 
 { 
     var temp = 100; 
     this.temp = 200; 
     return temp + this.temp; 
 } 

 alert(typeof(foo02)); 
 alert(foo02.constructor());    
运行结果:  object
 300    这是一个比较puzzle的function的使用方式,好像是定一个函数。但是实际上这是定一个JavaScript中的用户自定义对象,不过这里是个匿名类。这个用法和函数本身的使用基本没有任何关系,在大扩号中会构建一个变量作用域,this指代这个作用域本身。

    使用方法三:  
复制代码 代码如下:

var foo3 = new Function(''var temp = 100; this.temp = 200; return temp + this.temp;''); 

 alert(typeof(foo3)); 
 alert(foo3());    
运行结果:  function
 300    使用系统内置函数对象来构建一个函数,这和方法一中的第一种方式在效果和初始化优先级上都完全相同,就是函数体以字符串形式给出。

    使用方法四: 
 
复制代码 代码如下:

var foo4 = Function(''var temp = 100; this.temp = 200; return temp + this.temp;''); 

 alert(typeof(foo4)); 
 alert(foo4());    
运行结果:
function
300    这个方式是不常使用的,效果和方法三一样,不过不清楚不用new来生成有没有什么副作用,这也体现了JavaScript一个最大的特性:灵活!能省就省。

    关于函数初始化优先级这个问题,可以参看:"JS类定义原型方法的两种实现的区别"的回复。

functional继承模式 摘自javascript:the good parts_javascript技巧

functional继承模式 摘自javascript:the good parts_javascript技巧

这种模式的作用在于确保对象属性的真正私有化, 我们无法直接访问对象的状态, 只能通过特权方法来进行操作.
下面直接来个例子吧.

复制代码 代码如下:

var person = function(cfg) {
var that = {};
that.getName = function() {
return cfg.name || ''unknow name'';
};
// 性别 默认男性
that.getGender = function() {
return cfg.gender || ''male'';
};
return that;
};
var programmer = function(cfg) {
var that = person(cfg),
share = {};
share.status = ''normal'';
that.getFamiliarLanguage = function() {
return (cfg.langs || []).join('' '');
};
that.getProfile = function() {
return ''hi,my name is '' + that.getName();
};
that.getStatus = function() {
return share.status;
};
that.setStatus = function(status) {
share.status = status;
};
return that;
};
var me = programmer({
name: ''AndyZhang'',
gender: ''male'',
// 熟悉的语言
langs: [''javascript'', ''java'', ''php'']
});
console.debug(me.getFamiliarLanguage());
console.debug(me.getProfile());
me.setStatus(''oh really busy..'');
console.debug(me.getStatus());

从代码中可以看到,我们调用programmer方法时,没用使用new, 而且方法里也没有出现this关键字.
如果出现类似this.name = cfg.name这样的属性赋值代码, 再用new去调用(构造函数调用方式),这样产生的对象的name属性就不再私有.如:
复制代码 代码如下:

// 这里方法名的首字母大写 以表示作为一个构造方法 用new来调用
var Person = function(cfg) {
this.name = cfg.name;
this.gender = cfg.gender;
}
// new出一个person1
var person1 = new Person({
name: ''Andrew'',
gender: ''male''
});
// 本来是想让name, gender成为私有 用类似setter getter方法来读写 就像javaBean一样
alert(person1.name); // ''Andrew''
alert(person1.gender); // ''male''

从上面的例子可以看出person1的属性我们是可以直接访问的,没有做到真正的private. 有时候我们会用代码规范或约定来表示我们定义的某个属性是私有的,比如this._name用这样的写法表示name属性是私有的. 个人觉得只要约定统一,这也是一种不错的方式, 在第三方js库中,这种运用的可能比较多,像YUI2
继续看最开始的代码, 没有用到this, 而是用了that作为载体, 从programmer方法中我们看到that所起到的作用, 调用person后,返回的that已经具有了person所具有的方法getName, getGender, 然后我们根据programmer具体的需要在that基础上进行扩展, 当然也可以覆写原来的方法, programmer中的share可以用来集中一些私有变量和方法, 通过javascript的scope和closure机制, 可以在that扩展的方法中对它们进行处理和调用, 比如代码中的that.getStatus和that.setStatus方法, 最后return that.

关于JavaScrip Arrow Functions and This的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Calling Flex / Actionscript functions from Javascript、Function Definition, This and Bind in JavaScript、function, new function, new Function之间的区别_javascript技巧、functional继承模式 摘自javascript:the good parts_javascript技巧的相关知识,请在本站寻找。

本文标签: