弄懂 Sass 3.5 的匿名函数

发布于 2021-09-23 09:10:02 字数 6095 浏览 1351 评论 0

对博客上最新发布的 Sass 版本感到困惑?我也是。

Sass 3.5.0-RC.1标记了一种新的数据类型:匿名函数。在候选发布公告中,用了四个段落篇幅描述了 匿名函数 大量的细节,而不显示任何代码。由于并未真正理解它的含义,所以决定深入了解它。

匿名函数

候选版本上面写着:

可通过传函数名到 get-function($name) 中得到一个匿名函数

这说明 get-function($name) 返回的是一个匿名函数。

匿名函数是什么?

在计算机科学中,据说编程语言如果把函数当做一等公民来对待,那么它就有了匿名函数。-维基百科

听起来不错。好样的,functions,你得到了极大的提升。

然后,文中提到:

你可以在用来传递函数名的地方传递一个匿名函数给call()

这样做是有道理的,但仍缺乏几个例子。我当时想回答这样一个问题:“get-function($name)应该用在什么地方以及为什么要这样使用”

首先来看看从哪里开始。

在小于 3.5 的 Sass 版本中调用函数

两个选项:

my-function($arguments)

这是调用函数的经典方式。没什么值得惊讶的。

@function my-function() {
    @return ‘Hello, world.’;
}
my-function();// -> ‘Hello, world.’

或者使用call()

你或许对 call()方法不熟悉,这很正常。大多数开发者不需要用到它,因为它主要对库开发人员有用。

我们传递了一个函数名到call()方法,从而调用了该函数。

@function my-function() {
    @return ‘Hello, world.’;
}
call(‘my-function’); // -> ‘Hello, world.’

重要信息:Sass 3.5不支持这个选项。

所有目前用到传递字符串作为函数参数的样式表应该改用传递匿名函数代替。为此,  用字符串调用call()已被否决。 ** 实际上在4.0之前不会被废弃,它已没太大用处。但我们强烈建议用户立即切换到get-function()**。

例子:

@function foo($x) {
    @return $x;
}
foo('bar'); // -> 'bar'
// DEPRECATED: WILL BREAK IN Sass 4.0.0
call('foo', 'bar'); // -> 'bar'

我们来看看Sass 3.5.0及更高版本是如何处理选项2(call())方法的

在 Sass 3.5 及更高版本调用函数

在Sass 3.5中,你需要使用get-functioncall()传递一个匿名函数来调用函数。

my-function($arguments)

这依然有效,不必惊慌。

call(get-function(‘my-function’), $arguments)

现在您需要传一个匿名函数到call()方法而不是一个字符串:

@function foo($x) {
    @return $x;
}
h1 {
   content: call(
      get-function('foo'),
      'It works :)'
    );
}
h2 {
  content: call(
    get-function(foo),
      '(even without quotes)'
  );
 }
// call-get-function.scss
h1 { content: "It works :)"; }
h2 { content: "(even without quotes)"; }

call($my-function, $arguments)

没错,你还可以将函数指派给一个变量。

@​function my-function() {
    @​return ‘Great!’;
}
$my-function: get-function(my-function);// New in Sass 3.5.0!
call($my-function); // -> Great!

看一个简单的示例:

@function foo($x) {
    @return $x;
}
$foo: get-function(foo);
h1 {
  content: call($foo, 'bar');
}

不幸的是,$my-function()$foo('bar')将不起作用。编译将会失败,得到以下错误:

Error: get-function(“foo”) isn’t a valid CSS value.

乍一看,我认为可以在Sass中写 $a(b)是一件好事,但可能存在我没考虑到的影响。在未来版本中将如何发展,让我们拭目以待。

编写兼容所有Sass版本的代码

如你的mixin,library,或者framework需要支持多版本的Sass,有能写出兼容Sass 3.3以及更新的和未来版本的代码的办法。

使用function-exists

可以使用function-exists($name)判断get-function是否可用(意味着应传递一个匿名函数到call()方法)。如不可用,回退到旧版本的call语法(传递字符串):

@function foo($x) {
    @return $x;
}
h1 {
  @if (function-exists('get-function')) {
    content: call(get-function('foo'), 'Displays in Sass 3.5.0 and up');
  } @else {
    content: call('foo', 'Displays in Sass 3.3.x and 3.4.x');
   }
 }

// Unfortunately assigning a function to a variable
// can't be polyfilled for Sass 3.3.x and 3.4.x
$foo: get-function(foo);
h1 { content: call($foo, 'bar'); }
// -> el { content: get-function(foo)("bar"); }

使用 safe-get-function

我合并了一个 safe-get-function 的工具,在Sass旧版本和未来版本中都有效,所以你现在就可以在代码中使用get-function,为Sass 3.5和4.0做好准备。

// Simplified version of safe-get-function
// Full code: https://github.com/kaelig/sass-safe-get-function
@function safe-get-function($name) {
    @if function-exists('get-function') {
        @return get-function($name);
    } @else {
    @return $name;
   }
}
@function foo($x) { @return $x; }
h1 {
    content: call(safe-get-function('foo'), 'Works in all versions of Sass!');
}

safe-get-function()现可在npm上使用:

npm install sass-safe-function

可以在GitHub下载:https://github.com/kaelig/sass-safe-get-function

总结

即将发布的3.5版本并无革新性的变化,但我对在 Sass 4.0 版本的这些特性和新的模块系统感到兴奋,并非一切都在一个全局作用域内(这是一个重大变化)。

如果你的库或框架使用了 call() 方法,现在不失为一个好时机创建一个新的兼容 Sass 3.5 的分支,升级你的代码。使用 call(safe-get-function($name)) 代替 call($name)

如果你不是一个Sass库开发者,这些改变或许对你并没影响,但希望这篇文章让以后的 Sass 版本看起来没那么可怕。

想玩玩 get-function?我早已备好了一个仓库: https://github.com/kaelig/sass-first-class-functions,玩得开心。

扩展阅读

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

偏爱自由

暂无简介

0 文章
0 评论
21389 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文