导言
这是ECMAScript 2015标准中引入的JavaScript新特性 (也称为ES6) 如何为一些旧的JavaScript问题提供更简单的解决方案。在第1部分中,我介绍了块作用域和新的let和const关键字。在这里,我将查看函数的默认参数。
默认参数的旧方法
这是一个非常简单的JavaScript函数,用于将问候消息记录到控制台:
让greet = function(name){console.log (“嗨,我是” 的名字);}
这里有两个调用该函数的例子:
问候 (“猫王”); // 嗨,我是猫王greet(); // 嗨,我未定义
由于第二次调用greet没有传递任何参数,因此对console.log的调用只输出名称为 “未定义”。我们可以通过在函数内部使用逻辑或运算符 | | 并提供合适的名字对象来添加更合适的回退:
让greet = function(name){name = name | | "John Doe";console.log (“嗨,我是” 的名字);}问候 (“猫王”); // 嗨,我是猫王greet(); // 嗨,我是John Doe
有时 | | 的使用无法正常工作。这是一个函数的骨架,用于使用IgniteUI绘制数学函数y = x 2 1。(我故意遗漏了重要的方面,如图表标签,以保持代码最少)。
让makeChart = function($ selector,min,max){ “严格使用”; min = min | | -5;max = max | | 5;令步长 = (最大-最小)/10000;让数据 = [];for (设i = min; i ≤ max; i = i步长) {data.push({x:i, y:Math.pow(i,2) 1});}$ selector.igDataChart({数据源: 数据,宽度: “300px”,高度: “200px”,轴: [{名称: “xAxis”,类型: "numericX",最小值: 最小值,最大值: max,},{名称: “yAxis”,类型: “numericY”,最小值: 0}],系列: [{名称: "series1",类型: “散点线”,xAxis: "xAxis",yAxis: "yAxis",xMemberPath: "x",yMemberPath: "y",},],});}
假设三个浮动 (左) div元素-id为 “chart1”,“chart2” 和 “chart3”-我们可能会绘制三个这样的函数副本 (这里是jQuery对象 $ ):
makeChart($("# chart1" ));makeChart($("# chart2"), -3, 3);makeChart($("# chart3"), 0);
最终结果可能令人惊讶: 第三个图表与第一个图表相同,而不是x轴从0开始。
这是因为在第三次调用makeChart时传入的x轴最小值 (min) 的值为falsy。这意味着线
min = min | | -5;
将min更改为-5。
我们可以很容易地解决这个问题,但是通过显式地将min (和max) 与undefined进行比较,而不是检查真实性:
min = min!= = 未定义?最小值: -5;max = max!= = 未定义?最大: 5;
有了这个,第三个图表现在确实有一个从0开始的x轴。
更直观的默认参数
ES6使设置默认值更容易,如果你曾经用C或R编程,新的语法可能看起来很熟悉。只需为每个需要的函数参数添加一个等号和默认值。上面的makeChart示例变为:
让makeChart = function($ selector,min =-5,max = 5){ “严格使用”;令步长 = (最大-最小)/10000;让数据 = [];/* 函数的其余部分 */ }
在ES6兼容的浏览器中,这相当于上面的示例,其中我们将min和max与undefined进行了比较,但输入较少。我认为这也使代码更加透明,临时用户不再需要检查函数体以找到默认值。
前面的greet函数也可以简化:
let greet = function(name = "John Doe"){console.log (“嗨,我是” 的名字);}问候 (“猫王”); // 嗨,我是猫王greet(); // 嗨,我是John Doe
更复杂的例子
ES6默认值不必是简单的字符串或数字。您可以使用任何JavaScript表达式 ,后面的参数可以引用前面的参数。
将面向对象编程引入新编码器的一种常见方法是通过构造各种动物类和对象。JavaScript并不是真正的基于类的语言,但对象仍然很重要。对象工厂-返回对象的函数-是快速生成大量对象的简单方法。它们也是默认参数非常有用的地方。让我们创建一些会说话的狗 (!) 对象。以下是所有使用默认值的完全有效的ES6代码 (名称的默认值显然是在撰写本文时在此处列出的最受欢迎的雄性和雌性狗的名字):
让createDog = function(gender = “男性”,name =(gender === “男性” )?( “贝利”) :( “贝拉”),hobby = “吠叫”) {返回 {姓名: 姓名,性别: 性别,爱好: 爱好,sayName: function(){console.log("Hi,I'm " this.name); 返回此 ;},sayGender: function(){console.log("我是一个" 这个.gender "狗"); 返回这个 ;},sayHobby: function(){console.log (“我喜欢” 这个.hobby); 返回这个 ;},};};
下面是使用默认值的示例:
createDog().sayName().sayGender().sayHobby();
这个打印出来…
你好我是Bailey我是一只公狗我喜欢吠叫
我们可以指定所有参数,例如…
createDog (“女性”,“芭芭拉”,“获取”)。sayName()。sayGender()。sayHobby();
打印出来…
你好,我是芭芭拉我是一只母狗我喜欢取
我们还可以通过传入undefined来接受一个或多个参数的默认值。例如…
createDog (“女性”,未定义,“获取”)。sayName()。sayGender()。sayHobby();
导致输出
你好,我是贝拉我是一只母狗我喜欢取
请注意,这确实意味着当您不知道真实值时,您不能将undefined作为占位符传递。您可能想使用null。
默认名称的表达式不是特别健壮。例如,以下内容可能不是预期的内容:
createDog (“男性”)。sayName()。sayGender()。sayHobby();
你好,我是贝拉我是一只公狗我喜欢吠叫
在这种情况下,性别被设置为 “男性”,这与 “男性” 不匹配,因此默认的名称表达式会导致 “男性” 狗被称为贝拉。我们可以将第一个参数更改为isMale (或isFemale当然),并假设一个布尔输入。这可能是明智的选择。但它并没有很好地突出我们可以使用更复杂的表达式这一事实,所以我们不会。相反,我们将使用以下修改后的函数:
createDog = function(gender = "男",name =(gender.charAt(0).toUpperCase()=== "M" )?( "Bailey"):( "Bella"),hobby = "fetcing"){返回 {/* 对象不变 */};}
现在,出于默认名称分配的目的,任何以 “m” 或 “M” 开头的性别字符串都被视为男性。这可能意味着 “男性”,“男性”,“男人”,“m”,“M” 或 “果酱”。任何其他字符串-“女性”,“女性”,“JavaScript” 等-将名称设置为 “贝拉”,如果你不提供一个替代。这个版本也会抛出一个错误 (一件好事,一般来说),如果你传递一些真正愚蠢的性别 ,如 {} 或 /男性/。
重要的是要重述ES6默认值是从左边分配的。这可能是你宁愿名字是createDog函数的第一个参数。在没有name参数的情况下调用时,以下内容将不起作用,因为默认值的表达式在定义之前会尝试使用gender。
让createDog = function(name =(gender.charAt(0).toUpperCase()=== "M" )?( "Bailey"):( "Bella"),gender = "male",hobby = "reading"){返回 {/* 对象不变 */};}
如果你从Python或R这样的语言来到JavaScript,那么你可能会习惯在函数调用中使用默认参数旁边的命名参数。这在JavaScript中是不可能的。您可以做的最接近的是使用options对象代替多个参数。不幸的是,将options对象与ES6-style默认参数组合并不是特别容易 (有关详细信息,请参见此处 )。
现在完全支持Angular 2 Beta和Bootstrap 4,请参见什么是新的Ignite UI 16.1。下载今天免费试用。