整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

聊一聊JavaScript和Java、C#的“箭头函数”

S6 中引入了箭头函数,这也是现在前端面试几乎必考的内容(没考箭头函数,我都不好意思说自己是面试官,哈哈,开个玩笑)。有人问我,箭头函数是个什么东西?我跟他说,就像Java和C#中的lambda。

1. 举个简单的栗子:

1.1 JavaScript

let func = (s)=> { console.log(s); };

func("hello world");

1.2 Java

interface Operate {

void doSomething(String str);

// void doSomething1(); 不可以有两个方法

}

public static void main(String[] args) {

Operate func = (String s)->{ System.out.println(s);};

func.doSomething("hello world");

}

1.3 C#

var func = (string s)=> { Console.WriteLine(s); };

func("hello world");

1.4 分析

可以看到,写法非常类似,尤其是Js和C#。 变量func可以被当做一个函数来使用。

那么用于承接这个匿名方法的变量实际是什么?

JavaScript: 就是一个js中的function

Java: 在例子中,有点容易迷惑,明明是将lambda赋值给了一个接口类型。但最终调用的时候又要调用该接口的doSomething方法。而且这个接口只能有一个对应的方法,多了会报错。

Java10中也提供了var关键字,但遗憾的是也不能被用于这样lambda赋值的情况。

C#: 实际上是一个委托类型,例如:

delegate void doSomething(string str);

public static void Main(string[] args) {

doSomething func = (string s) => { Console.WriteLine(s); };

func("hello world");

}

这样看和Java有点像了,但定义的仍然是一个方法,而不是一个接口中有一个同样类型的方法。

如果在c语言中我们会用一个指向函数的指针。

2. 对函数外变量的引用

在上一节的例子中,“hello world”是以参数的形式传递到方法中的,那么,是否可以直接引用外部的方法呢?

当然是可以的,改造一下上面的例子:

2.1 JavaScript

let str = ",圣诞快乐。";

let func = (s)=> {

console.log(s + str);

str = ",春节快乐。"

};

str = ",元旦快乐。"

func("hello world");

func("hello world");

2.2 Java

interface Operate {

void doSomething(String str);

// void doSomething1(); 不可以有两个方法

}

public static void main(String[] args) {

final String str = ",圣诞快乐";

Operate func = (String s)->{

System.out.println(s + str);

//str = ",春节快乐。";

};

//str = ",元旦快乐。"

func.doSomething("hello world");

}

2.3 C#

var str = ",圣诞快乐。";

var func = (string s) => {

Console.WriteLine(s + str );

str = ",春节快乐。";

};

str = ",元旦快乐。";

func("hello world");

func("hello world");

2.4 分析

  • JavaScript 和C# 的结果是一样的,输出结果为:

hello world,元旦快乐。

hello world,春节快乐。

可见,在函数执行的时候,会取当时str的值。在函数定义的时候,虽然引用了变量str,但不是此时固定了str的值。

在函数中改变了str的值,会改变外部str的值。

Java的例子中,要求str是final的才行,所以是无法对str改变的。

3. 作为方法的参数

在JavaScript中,经常会用到类似callback的回调方法,那么箭头函数是不是也可以呢?

3.1 JavaScript

let func = (s)=> {

console.log(s);

};

var showLog = function(str,action){

action(str);

}

showLog("hello world",func);

3.2 Java

本例用Consumer代替了第一节中的自定义的Operate接口。其实Consumer就是框架帮我们预定义的泛型接口,避免我们总需自定义一个接口:

public static void main(String[] args) {

Consumer<String> func = (String s)->{

System.out.println(s);

};

showLog("hello world",func);

}

public static void showLog(String str, Consumer<String> action){

action.accept(str);

}

3.3 C#

本例用Action代替了第一节中的自定义的delegate。其实Action就是框架帮我们预定义的泛型接口,避免我们总需自定义委托:

public static void Main(string[] args)

{

var func = (string s) => { Console.WriteLine(s); };

showLog("hello world", func);

}

public static void showLog(string str ,Action<string> action)

{

action(str);

}

4. 总结

总体来说,三种语言的使用方法还是比较类似的。可能是都源于C的原因?

其实对于面向对象语言来说,好多都是相通的,个人感觉经常对比一下,有助于加深记忆。

另外,如果有机会,学一门风格和自己擅长的开发语言差异比较大的,更有利于对编程语言的了解。

————————————————

版权声明:本文为CSDN博主「FlyLolo」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Lolo_cs_dn/article/details/122159246

周我发表了一篇为初学者介绍 this 关键字的博文。

(JavaScript: 为初学者介绍 new 运算符)

这篇文章中没有涉及到的主题之一是箭头函数。这个主题只是因为太大,没法在那篇文章中讲解,所以本文在这里做一个补充。请继续阅读,学习有关箭头函数的基础知识!

好处 #1: 更短的语法

下面我们先看一个普通的函数:

function funcName(params) {

return params + 2;

}funcName(2);// 4

上述代码预示了创建箭头函数的两个原因之一:更短的语法。完全相同的函数可以被表示为只有一行代码的箭头函数:

var funcName = (params) => params + 2funcName(2);// 4

很棒。这个示例显然是极端简化的,不过但愿也能阐明我的观点。下面我们稍微更深入地看看箭头函数的语法:

(参数) => { 语句 }

如果没有参数的话,我们就像下面这样表示箭头函数:

() => { 语句 }

当只有一个参数时,圆括号是可选的:

参数 => { 语句 }

最后,如果要返回一个表达式,就要把大括号删掉:

参数 => 表达式// 等价于:function (参数){ return 表达式;

}

好了,现在你知道了语法,来个示例怎么样?打开 Chrome 开发者控制台 (Windows: Ctrl + Shift + J)(Mac: Cmd + Option + J),并键入如下代码:

var double = num => num * 2

如你所见,我们正把一个箭头函数赋值给变量 double。这个箭头函数只有一个参数 num。因为只有一个参数,所以我们就可以省略括住参数的圆括号。因为我们想返回 num * 2 的值,所以也省略了括住要返回的表达式的大括号。下面我们调用该函数,看看其结果:

double(2);// 4double(3);// 6

好处 #2: 不绑定 this

在继续之前,你应该很好地理解 this 关键字及其工作机制。

与普通函数不同,箭头函数不需要绑定 this,而是词法绑定 this(即,this 保持它在原始上下文中的含义)。

有个示例应该会让这更清楚一些。在控制台中,创建一个构造器函数,然后创建它的一个实例:

function Counter() { this.num = 0;

}var a = new Counter();

从上一篇文章你应该知道,构造器函数中 this 的值被绑定到正在新创建的对象,在本例中,就是 a 对象。这就是为什么我们输出 a.num 会得到 0 的原因。

console.log(a.num);// 0

如果想把 a.num 的值每秒钟增加该怎么办呢?我们可以用 setInterval() 函数。setInterval() 是一个会在设定的毫秒数之后重复调用另一个函数的函数。下面我们把它加到 Counter 函数中:

function Counter() { this.num = 0; this.timer = setInterval(function add() { this.num++; console.log(this.num);

}, 1000);

}

上面的代码除了加了一个变量 this.timer,并把它设置为等于 setInterval 函数外,其它的看起来与之前没什么两样。每隔1000微秒(即1秒)代码就会执行一次。this.num 会加一,然后被输出到控制台上。下面我们试一试,在控制台中创建再次创建 Counter 的一个实例:

var b = new Counter();// NaN// NaN// NaN// ...

如你所见,函数会每秒都会输出到屏幕上一次。不过这结果不是我们想要的。NaN(Not a Number)一直被输出。那么是哪里出错了呢?首先,运行如下代码终止烦人的输出:

clearInterval(b.timer);

我们再回去看看代码。setInterval 函数不是在一个声明过的对象上调用的,也不是用 new 关键字调用的(只有 Counter() 函数是)。而且最后,我们没有用 call、bind 或 apply。setInterval 只是一个普通函数。实际上,setInterval 中 this 的值被绑定到了全局对象上!下面我们通过输出 this 的值来验证一下这个推测:

function Counter() { this.num = 0;this.timer = setInterval(function add() { console.log(this);

}, 1000);

}var b = new Counter();

你会看到,window 对象每秒被输出一次。通过执行如下代码清除掉时间间隔:

clearInterval(b.timer);

回到原始函数。它之所以输出 NaN,是因为 this.num 引用的是 window 对象上的 num 属性(而 window.num 是不存在的),而不是我们刚创建的 b 对象(b.num)。

那么我们该如何纠正呢?用箭头函数!我们需要一个不绑定 this 的函数。用箭头函数的话,this 就会一直是其上下文的原始绑定。下面把原始 Counter 函数中的 setInterval 用箭头函数替换:

function Counter() { this.num = 0; this.timer = setInterval(() => { this.num++; console.log(this.num);

}, 1000);

}var b = new Counter();// 1// 2// 3// ...

我们会看到,控制台开始输出递增的数字 - 它起作用了!Counter 构造器函数创建的原始 this 绑定被保留下来了。在 setInterval函数内,this 依然被绑定到了我们新创建的 b 对象上!

我们可以用如下代码清除掉时间间隔:

clearInterval(b.timer);

为证明这种机制,我们再试在箭头函数内输出 this。我们将在 Counter 函数中创建一个名为 that 的变量。然后如果 setInterval函数中的 this 的值等于父函数 Counter 中的 this(通过 that)的值,那么就会输出 true:

function Counter() { var that = this;this.timer = setInterval(() => { console.log(this === that);

}, 1000);

}var b = new Counter();// true// true// ...

不出所料,每次都会输出 true!再次用如下语句清除时间间隔:

clearInterval(b.timer);

总结

希望本文能帮助大家看到箭头函数的两个主要好处:

  1. 语法更短
  2. 不绑定 this

声明一下,箭头函数涉及的知识比本文所解释的要多。但是本文应该已经为深入学习打下了很好的基础。

如果大家有关于技术的任何问题

或者想了解更多的技术干货私聊然后可以加朗妹儿微信哟~

为前端工程师来说,css3的运用无疑是很广泛的,实现的奇妙效果也是丰富多彩。它的优点远不止于能让你的页面酷炫非常,一个好的css3运用能给体验者一种莫名的心旷神怡嘿嘿嘿!

下面来看看百度是怎么使用css3的

这是百度的首页。链接:http://xuanfengge.com/demo/201406/guide/

下面我们说说这是怎么实现的。

首先箭头是一张图片,然后效果其实就是用2个相同的DOM元素利用缩放动画使这两个箭头交叉闪烁。

代码附上:

//两个箭头的html

<a class="s-xguide-down trans" href="http://www.baidu.com/" onclick="return false;" hidefocus=""></a>

<a class="s-xguide-down arrow-1 trans" href="http://www.baidu.com/" onclick="return false;" hidefocus=""></a>

css代码如下

图片样式css

css3缩放动画

css3缩放动画

效果引用

这个效果主要运用到了@keyframes的生成动画,利用css3的scale对两张图片进行缩放、透明度的交叉,最终得到动画的实现。

一个基础的css3教程希望能给刚入门的小伙伴们带来帮助,快动手试试吧!