博客原文地址:Claiyre的个人博客 https://claiyre.github.io/

博客园地址:http://www.cnblogs.com/nuannuan7362/

如需转载,请在文章开头注明原文地址

前言

众所周知,css是静态语言,虽功能强大,但用起来还是略微不爽,于是便有了动态样式语言,sass和less。动态样式语言的精髓就在于其有了变量,其中的诸多功能都是建立在变量之上的。因此,彻底弄懂sass和less中变量的异同之处,是学好它们的关键!

本文由浅至深,逐步展开介绍,并从大家所熟知的JS变量的角度,讲述sass和less变量作用域。

正文

sass和less都允许使用变量,且对变量的类型没有限制,这一点和js极为相似,非常灵活。但两者的不同都有哪些呢?

变量标识符不同

sass中规定,以美元符号 $ 开头的即表示变量,而less中以符号 @ 开头表示变量。这点很容易理解,不再多说。

变量插值方式不同

在两种语言中,变量都可以以一定的方式插入到字符串中去,这个特性极为有用,但两种语言的插入方式不同,具体请看下例:

//sass 中

$direction: left;
.myPadding{
padding-#{$direction}: 20px;
} //less中 @direction: left; .myPadding{
padding-@{direction}: 20px;
} //编译后的css代码是相同的,如下: .myPadding{
padding-left: 20px;
}

变量作用域

在sass 3.4.0之前,sass可以说是没有局部变量和全局变量之分的,即后声明的同名变量总是会覆盖之前的同名变量,不管后声明的变量是位于何处。

此时,less和sass的变量作用域有很大的不同之处。先看一段熟悉的js代码:

//代码块A

var a = 1;
(function (){
a = 5;
alert(a); //a = 5;
})();
alert(a); //a = 5;

由于闭包的作用,匿名函数内部可以引用到外部的变量a,因此上面的代码可以正常运行。再来看下面这个:

//代码块B

var a = 1;
(function (){
var a = 5;
alert(a); //a = 5;
})();
alert(a); //a = 1;

了解js链式作用域的朋友一定秒懂了上面的代码。

在匿名函数的内部声明了一个局部变量,局部变量并不会影响全部变量,所以代码最后输出的仍然是1。

那么回到正题,sass 3.4.0之前 的变量设计思想是类似于代码块A的,即不带关键字var的局部变量声明,而less的思想类似代码块B,带关键字var的局部变量声明。

看到这,很多人估计就想开始吐槽sass不人性化的设计了,万一我一不小心声明了一个局部变量,它和某个全局变量同名了,那不岂不是要酿成大祸!

大家先别急着吐槽,人家sass这不是也改进了嘛~ 而且sass不仅改了,还附送了彩蛋 !global

sass官网上 3.4.0版本的 Backwards Incompatibilities – Must Read! 中有这样一条:

All variable assignments not at the top level of the document are now local by default. If there’s a global variable with the same name, it won’t be overwritten unless the !global flag is used. For example, $var: value !global will assign to $var globally. This behavior can be detected using feature-exists(global-variable-shadowing).

翻译过来便是:没有位于第一层(全局)的变量声明现在都被默认为是局部的。如果存在一个同名的全局变量,这个全局变量也不会被重写,除非同名的局部变量被声明时使用关键字!default

举例说明:

$color: blue;
a{
$color: red;
color: $color; //red
}
p{
color: $color; //blue
} //但是,若使用 !global span{
$color: yellow !global;
color: $color; //yellow
}
div{
color: $color; //yellow
}

上面的代码没有什么实际意义,但作为例子,简洁明了便好。

有一点需要说明的是,sass 3.4.0 是在14年8月份发布的,但现在网上的关于sass变量的文章对作用域的说明,大多仍旧停留在3.4.0之前。希望大家能注意sass这个重要的改进,以免在开发过程中带来不便。在此也得出一个血泪教训,尽量看英文官方文档啊啊啊啊

结语

sass和less两种动态样式语言的诞生,赋予了css更大的灵活性,在学习使用的过程中,一定要注意区分两者的不同,灵活运用。

参考:

以上仅我个人见解,如有错误之处,欢迎指正。如您觉得我的文章对您有帮助,请点击下方“推荐”,让更多的人看到。

细谈sass和less中的变量及其作用域的更多相关文章

  1. Python中的变量和作用域详解

    Python中的变量和作用域详解 python中的作用域分4种情况: L:local,局部作用域,即函数中定义的变量: E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部 ...

  2. Shell中脚本变量的作用域

    原文地址:http://blog.csdn.net/abc86319253/article/details/46341839    在shell中定义函数可以使代码模块化,便于复用代码.不过脚本本身的 ...

  3. python with语句中的变量有作用域吗?

    一直以为python中的with语句中的变量,只在with语句块中起作用.不然为什么要缩进一个级别呢? 呵呵,然而并没有为with语句内的变量创建新的作用域. 举例: # test.py with o ...

  4. python中对变量的作用域LEGB、闭包、装饰器基本理解

    一.作用域 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域.python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量 ...

  5. 一篇文章带你了解JavaScript中的变量,作用域和内存问题

    1 在JavaScript中的变量分别区分为两种: 一种为基本类型值,一种为应用类型值. 基本类型值指的是简单的数据段 引用类型值为可能由多个值组成的对象 引用类型的值是保存在内存中的对象,JavaS ...

  6. 第5.4节 Python函数中的变量及作用域

    一.函数中的变量使用规则 函数执行时,使用的全局空间是调用方的全局空间,参数及函数使用的局部变量存储在函数单独的局部名字空间内: 函数的形参在函数中修改了值时,并不影响调用方本身的数据,但如果形参是一 ...

  7. [转] 浅谈JS中的变量及作用域

    Situation One <script> var i; function sayHello() { var x=100; alert(x); x++; } sayHello();   ...

  8. javascript中的变量、作用域和内存问题

    1.变量 变量的值的类型:基本类型值和引用类型值两种. 基本类型:Undefined.Null.Boolean.String.Number,这五类基本数据类型的值在内存中占有固定大小的空间,因此保存在 ...

  9. OpenCV-Python setMouseCallback回调函数中图像变量img的传递方法解析

    ☞ ░ 前往老猿Python博文目录 ░ 一.使用全局变量进行变量传递 OpenCV-Python中可以使用setMouseCallback来设置鼠标事件的回调函数,我们来看个样例. 1.1.案例1代 ...

随机推荐

  1. UVa 10306 - e-Coins

    题目大意:现在有一种新型货币,它的价值分为传统价值x和IT价值y,价值计算方式为sqrt(x*x+y*y),现给一些类型的货币和要达到的目标价值,计算达到目标所需的最少货币数目.注意计算方法是sqrt ...

  2. 【Xilinx-Petalinux学习】-08-OpenAMP系统实现

    openAMP系统实现. 一个核跑Linux,一个核裸跑.     ----->  已经实现. 一个核跑Linux,一个核跑UCOS   ----->  还未实现. Micrium的uco ...

  3. Struts2配置dtd约束

    Struts2和Struts1的区别: 一.elclipse-ee开发 搭建环境eclipse-ee 1.加入jar包  apps/struts2-blank.war解压 2.在web.xml文件中配 ...

  4. [UT]Unit Test理解

    Coding中有一个原则:Test Driven Development.  UT中的一些基本概念: 1. 测试驱动 2. 测试桩 3. 测试覆盖 4. 覆盖率 单体测试内容: 1. 模块接口:测试模 ...

  5. 分享Grunt.js配置: watch + liveReload 实时监测文件变化自动刷新浏览器

    http://www.tuicool.com/articles/2eaQJn 用Grunt配置watch和liveReload组件,可以实时检测指定的文件变化并自动刷新浏览器.目前基本已经成为了我的必 ...

  6. JS的组成部分、引入页面的方法以及命名规范

    JS的组成部分.引入页面的方法以及命名规范   一.页面是由三部分组成 1)html标签(超文本标记语言) 2)css样式(层叠样式表) 3)javascript脚本编程语言(动态脚本语言) 二.将c ...

  7. C# 安装包制作

    VS制作安装包的一般步骤. 一·新建项目 (1)新建 (2)界面跳转 二·添加引用 (1)添加卸载程序 1.在'C:WINDOWSsystem32'路径下,找到msiexec.exe . 2.将msi ...

  8. Nodejs.sublime-build 在sublime3中的配置

    { "cmd": ["node", "$file"], "file_regex": "^[ ]*File \& ...

  9. C# 定时器计划任务

    函数类: public class MyPlan { public void RunMyplan(object source, ElapsedEventArgs e) { //读取配置文件设定的日期时 ...

  10. Bloom Filter的基本原理和变种

    学习一个东西首先要知道这个东西是什么,可以做什么,接着再了解这个东西有什么好处和优势,然后再学习他的工作原理.下面我们分别从这三点简单介绍一下bloom filter,以及和他的变种. What:在允 ...