函数也是个物件型别,可以封装一些功能(程序码),在需要使用的时候执行功能(程序码)。
例如我们需要把数字相加,在没有函式的时候,需要用的时候就要重复打程序码:
let x = 1;
let y = 1;
let result = x + y;
console.log( result ); // 2
x = 3;
y = 2;
result = x + y;
console.log( result ); // 5
而我们学程序,讲求的就是效率,所以自己定义一个函式封装相加功能:
function sum (x, y) {
let result = x + y;
console.log( result );
}
sum(1, 1); // 2
sum(3, 2); // 5
从上面的函式结构我们可以看到
上面已经使用了一个建创方法
function 函式名 (参数) {
/* 运作程序码功能 */
}
函式名 (参数);
上面有说函式名称不一定会有,匿名函式就是没有自己的名称,而是直接赋值给变数使用,又称函式表达式。
const 变数名 = function (参数) {
/* 运作程序码功能 */
}
变数名 (参数);
跟物件与阵列一样,使用 new Function
新增函式。
需注意:
const 变数名 = new Function ("参数", "运作程序码");
但这个方法并不好用,而且效率低,因为程序码会先把字串转成它看得懂的程序码,才进行运算。
我们会运用功能了,但不想一直使用 console.log
印出来,想要让函式结果继续在程序码里面运算。
可以利用 return
把运算结果返回并终止函式。
function sum (x, y) {
const res = x + y;
return res; // 使用 result 返回值,并终止函式
console.log("测试有没有执行") // return 後的程序码不会执行
}
const result = sum(1, 1); // 返回的值 赋予到 result 变数上
console.log( result ); // 2
有些时候,我们只想在一开始使用一次函式,後续不会调用函式,就像进入超商会听到欢迎光临一样。
此时不想占用变数空间,就可以使用匿名函式立即执行,需注意:
()
包起来,不然 JavaScript 会认为你忘记为函式命名而报错。( function(text) {
console.log(text)
} )("欢迎光临")
或
( function(text) {
console.log(text)
}("欢迎光临") )
都可以使用,看个人(团体)习惯
在我们宣告变数那一篇有介绍,全局作用域 与 函数作用域。
直接编写 script 标签中 JavaScript 程序码,都会在全局作用域。
var a = 1;
console.log(a); // 1
全局作用域在网页打开时创建,在关闭网页时清除。
在全局作用域有一个叫 window
的物件,代表浏览器的视窗,它由浏览器新增并供我们使用其内建的方法。
console.log(typeof window); // "object"
在全局作用域中
宣告变数都会变成 window 的属性保存
var a = 1;
console.log(window.a); // 1
新增的函式会变成 window 的方法保存
function sum (x,y) {
return x + y;
}
console.log( window.sum );
/*
function sum (x,y) {
return x + y;
}
*/
我们先从全局作用域看变数,会发现不管有没有使用 var
宣告都会取得到值
var a = 1;
x = 2;
console.log("a = "+ a); // "a = 1"
console.log("x = "+ x); // "x = 2"
这时候我们把变数往後移,因为 Javascript 是由上向下一行一行执行,会发现有没有宣告的差别。
console.log("a = "+ a); // "a = undefined"
console.log("x = "+ x); // 报错 x is not defined
var a = 1;
x = 2;
有先进行 var
声明宣告的变数,在执行程序码之前会先提升至全局作用域的开头,才执行程序码,相当於:
var a // var 声明宣告会自动提升
console.log("a = "+ a); // "a = undefined"
console.log("x = "+ x); // 报错 x is not defined
a = 1;
x = 2;
一样的,函数也会在程序执行前,会先自行提升,但函式有两个新增方法,一个是函式陈述式,一个是函式表达式。
与上面一样正常使用的话是不会报错,但如果反过来?
fun() // "我是一个 fun 函式"
fun2() // 报错 fun2 is not a function
function fun () {
console.log("我是一个 fun 函式")
}
var fun2 = function () {
console.log("我是一个 fun2 函式")
}
我想聪明的你,应该马上就猜想到,没错!就是宣告变数提前,但变数的函式要到後面才会赋值,undefined
当函式使用当然会报错!
而使用函式陈述式,会把整个函式提升,在执行程序码!
function fun () { // 函式陈述式把整个函式提升
console.log("我是一个 fun 函式")
}
var fun2; // var 自动提升宣告 undefined
fun() // "我是一个 fun 函式"
fun2() // 报错 fun2 is not a function
fun2 = function () { // 到这里才赋值
console.log("我是一个 fun2 函式")
}
编写在函式里面的 Javascript 程序码,这个区域就称函式作用域。
函式作用域只在函式被调用时创建,在函式执行结束时清除。
每调用一次函式会创建一个新的函式作用域,函式作用域彼此都是独立运作的。
函式作用域可以往外查找全局作用域的变数,全域作用域不能往内查找函式作用域的变数。
var a = 1;
function echo () {
var b = 2;
console.log("a = "+ a); // "a = 1",函式内没有 a 变数,会往全域找 a 变数
}
echo();
console.log("b = "+ b); // 报错 b is not defined,全域找不到 b 变数
函式作用域中操作变数时,会先在自己的作用域寻找,没有则会往上一层去寻找变数,一路查到全局作用域,直到找到为止,如果找不到就会报错。
var a = "我是全局的 a";
var c = "我是全局的 c";
function echo () {
var a = "我是 echo 内的 a";
var b = "我是 echo 内的 b";
console.log("a = "+ a); // "a = 我是 echo 内的 a",函式内有 a 变数,优先使用
console.log("a = "+ window.a); // "a = 我是全局的 a",利用 window 直接查找全局变数
function inside () {
console.log("b = "+b); // "b = 我是 echo 内的 b",
// 函式内没有 b 变数,往上一层 echo 内查找到 b 变数
console.log("c = "+c); // "c = 我是全局的 c",
// 函式内没有 c 变数,往上一层 echo 内也查找不到变数,再往上一层查找。
}
}
echo();
console.log("a = "+ a); // "a = 我是全局的 a",不会查找函式内的值
定义参数,其实就等於在函式内宣告变数,所以就不会往外查找变数。
var e = 1;
function echo (e) {
console.log(e);
}
echo(); // undefined,因为 var e; 是 undefined
echo(10); // 10
这边已经先了解了基础的函式,但函式的精随 this
还没介绍,介绍函式的同时也了解了宣告变数 var
的作用域与提升了~但宣告变数还有 let
与 const
的特性还没有介绍!这等到後面要认识函式的精随的时候,在一起解说~明天将先继续挖深物件型别,加油!我们快脱离基础篇了。
上次学的Spinner需要点选下拉钮,才显示项目 而ListView则是直接把所有项目列出来 两者的...
图片来源:unsplash 关於资料视觉化的工具一般使用者最先接触的可能是Microsoft Ex...
笔者在做UART传输专案时遇到需要将收到的资料撷取後面不同长度的资料,再填入不同的公式中 预设的作业...
Given a string s, find the length of the longest s...
表单类型是网页很常见的呈现方式,表单元素有文字框<input>、<textarea...