1.JavaScript 函数
1.1 JavaScript 函数定义
JavaScript 使用关键字function 定义函数
函数可以通过声明定义,也可以是一个表达式。
函数声明
函数声明语法:
function functionname(num1){
执行的代码
}
函数声明后不会立即执行,虎仔我们需要到时候调用到。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>本例调用的函数会执行一个计算,然后返回结果:</p>
<p id="demo"></p>
<script>
function myFunction(a,b){
return a*b;
}
document.getElementById("demo").innerHTML=myFunction(4,3);
</script>
</body>
</html>
分号是用来分隔可执行JavaScript语句。
由于函数声明不是一个可执行语句,所以不以分号结束。
函数表达式
JavaScript 函数通过一个表达式定义。
函数表达式可以存储在变量中
var x=function(a,b){return a*b};
在函数表示存储在变量后,变量也可以作为一个函数使用。
var x=function(a,b){return a*b};
var z=x(4,3);
以上函数实际上是一个匿名函数(函数没有名称)。
函数存储在变量中,不需要函数名称,通常通过变量名来调用。
function() 构造函数
在以上实例中,我们了解到函数通过关键字function定义。
函数同样可以通过内置的JavaScript函数构造器(Function())定义。
var myFunction = new Function("a","b" ,"return a*b");
var x=myFunction(4,3);
实际上,你不必使用构造函数。上面实例可以写成:
var myFunction =function (a,b){return a*b};
var x=myFunction(4,3)
在JavaScript中,很多时候,你需要避免使用new关键字。
函数提升(Hoisting)
在之前的教程中我们已经了解了 "hoisting(提升)"
提升(Hoisting)是JavaScript默认将当前作用域提升到前面去的行为。
提升(Hoisting)应用在变量的声明与函数的声明。
因此,函数可以在声明之前调用:
myFunction(5);
function myFunction(y) {
return y * y;
}
使用表达式定义函数时无法提升。
自调用函数
函数表示可以“自调用”。
自调用函数表达式会自动调用。
如果表达式后面紧跟(),则会自动调用
不能自调用声明的函数。
通过添加括号,来说明它是一个函数表达式:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>函数可以自动调用:</p>
<p id="demo"></p>
<script>
(function () {
document.getElementById("demo").innerHTML = "Hello! 我是自己调用的";
})();
</script>
</body>
</html>
以上函数实际上是一个匿名自我调用的函数(没有函数名)
函数可作为一个值使用
JavaScript函数作为一个值使用。
function myFunction(a, b) {
return a * b;
}
var x = myFunction(4, 3);
JavaScript 函数可作为表达式使用:
function myFunction(a, b) {
return a * b;
}
var x = myFunction(4, 3) * 2;
函数是对象
在JavaScript中使用 typeof 操作符判断函数类型将返回 "function" 。
但是JavaScript 函数描述为一个对象更加准确。
JavaScript 函数有 属性 和 方法。
arguments.length 属性返回函数调用过程接收到的参数个数.
function myFunction(a, b) {
return arguments.length;
}
toString() 方法将函数作为一个字符串返回.
function myFunction(a, b) {
return a * b;
}
var txt = myFunction.toString();
1.2JavaScript 函数参数
JavaScript 函数对参数的值没有进行任何的检查。
函数显示参数(Parameters)与隐式参数(Arguments)
在先前我们已经学习了函数的显示参数:
functionName(parameter1, parameter2, parameter3){ // 要执行的代码}
函数显示参数在函数定义时列出
函数隐式参数在函数调用时传递给函数真正的值。
参数规则
JavaScript 函数定义显示参数时没有指定数据类型。
JavaScript 函数对隐式参数没有进行类型测试。
JavaScript 函数对隐式参数的个数没有进行检测。
默认参数
ES5中如果函数在调用时未提供隐式参数,参数会默认设置为: undefined
有时这是可以接受的,但建议最好为参数设置一个默认值:
function myFunction(x, y) {
if (y === undefined) {
y = 0;
}
}
或者,更简单的方式:
function myFunction(x, y) {
y = y || 0;
}
如果y已经定义 , y || 返回 y, 因为 y 是 true, 否则返回 0, 因为 undefined 为 false。
如果函数调用时设置了过多的参数,参数将无法被引用,因为无法找到对应的参数名。 只能使用 arguments 对象来调用。
ES6 函数可以自带参数
ES6 支持函数带有默认参数,就判断 undefined 和 || 的操作.
function myFunction(x, y = 10) {
// y is 10 if not passed or undefined
return x + y;
}
myFunction(0, 2) // 输出 2
myFunction(5); // 输出 15, y 参数的默认值
arguments 对象
JavaScript 函数有个内置的对象 arguments对象。
arguments 对象包含了函数调用的参数数组。
通过这种凡是你可以很方便的找到最大的一个参数的值。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>查找最大的数。</p>
<p id="demo"></p>
<script>
x = findMax(1, 123, 500, 115, 44, 88);
function findMax() {
var i, max = arguments[0];
if(arguments.length < 2) return max;
for (i = 0; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
document.getElementById("demo").innerHTML = x;
</script>
</body>
</html>
或者创建一个函数用来统计所有数值的和。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>计算所有参数之和:</p>
<p id="demo"></p>
<script>
function sumAll() {
var i, sum = 0;
for(i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
document.getElementById("demo").innerHTML =sumAll(1, 123, 500, 115, 44, 88);
</script>
</body>
</html>
通过值传递参数
在函数中调用的参数是函数的隐式参数。
JavaScript 隐式参数通过值来传递:函数仅仅只是获取值。
如果函数修改参数的值,不会修改显示参数的初始值(在函数外定义)。
隐式参数的改变在函数外是不可见的。
通过对象传递参数
在JavaScript中,可以引用对象的值。
因此我们在函数内部修改对象的属性就会修改其初始的值。
修改对象属性可作用于函数外部(全局变量)。
修改对象属性在函数外是可见的。
1.3JavaScript 函数调用
JavaScript 函数有 4 种调用方式。
1.作为一个函数调用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>
全局函数 (myFunction) 返回参数参数相乘的结果:
</p>
<p id="demo"></p>
<script>
function myFunction(a, b) {
return a * b;
}
document.getElementById("demo").innerHTML = myFunction(10, 2);
</script>
</body>
</html>
以上函数不属于任何对象。但是在 JavaScript 中它始终是默认的全局对象。
在 HTML 中默认的全局对象是 HTML 页面本身,所以函数是属于 HTML 页面。
在浏览器中的页面对象是浏览器窗口(window 对象)。以上函数会自动变为 window 对象的函数。
myFunction() 和 window.myFunction() 是一样的.
全局对象
当函数没有被自身的对象调用时this的值就会变为全局对象
在 web 浏览器中全局对象是浏览器窗口(window 对象)。
该实例返回 this 的值是 window 对象.
function myFunction() {
return this;
}
myFunction(); // 返回 window 对象
2.函数作为方法调用
在 JavaScript 中你可以将函数定义为对象的方法。
以下实例创建了一个对象 (myObject), 对象有两个属性 (firstName 和 lastName), 及一个方法 (fullName).
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>myObject.fullName() 返回 John Doe:</p>
<p id="demo"></p>
<script>
var myObject = {
firstName:"John",
lastName: "Doe",
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
document.getElementById("demo").innerHTML = myObject.fullName();
</script>
</body>
</html>
fullName 方法是一个函数。函数属于对象。 myObject 是函数的所有者。
this对象,拥有 JavaScript 代码。实例中 this 的值为 myObject 对象。
测试以下!修改 fullName 方法并返回 this 值.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>在一个对象方法中 ,<b>this</b> 的值是对象本身。</p>
<p id="demo"></p>
<script>
var myObject = {
firstName:"John",
lastName: "Doe",
fullName: function() {
return this;
}
}
document.getElementById("demo").innerHTML = myObject.fullName();
</script>
</body>
</html>
函数作为对象方法调用,会使得 this 的值成为对象本身。
使用构造函数调用函数
如果函数调用前使用了 new 关键字, 则是调用了构造函数。
这看起来就像创建了新的函数,但实际上 JavaScript 函数是重新创建的对象.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>该实例中, myFunction 是函数构造函数:</p>
<p id="demo"></p>
<script>
function myFunction(arg1, arg2) {
this.firstName = arg1;
this.lastName = arg2;
}
var x = new myFunction("John","Doe")
document.getElementById("demo").innerHTML = x.firstName;
</script>
</body>
</html>
构造函数的调用会创建一个新的对象。新对象会继承构造函数的属性和方法。
构造函数中 this 关键字没有任何的值。
this 的值在函数调用实例化对象(new object)时创建。
作为函数方法调用函数
在 JavaScript 中, 函数是对象。JavaScript 函数有它的属性和方法。
call() 和 apply() 是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。
call()
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var myObject;
function myFunction(a, b) {
return a * b;
}
myObject = myFunction.call(myObject, 10, 2); // 返回 20
document.getElementById("demo").innerHTML = myObject;
</script>
</body>
</html>
apply()
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var myObject, myArray;
function myFunction(a, b) {
return a * b;
}
myArray = [10, 2]
myObject = myFunction.apply(myObject, myArray); // 返回 20
document.getElementById("demo").innerHTML = myObject;
</script>
</body>
</html>
2.JavaScript 对象
2.1 JavaScript 对象
JavaScript 中的所有事物都是对象:字符串、数值、数组、函数...
此外,JavaScript 允许自定义对象。
JavaScript 提供多个内建对象,比如 String、Date、Array 等等。 对象只是带有属性和方法的特殊数据类型。
布尔型可以是一个对象。
数字型可以是一个对象。
字符串也可以是一个对象。
日期是一个对象。
数学和正则表达式也是对象。
数组是一个对象。
甚至函数也可以是对象。
对象只是一种特殊的数据。对象拥有属性和方法。
访问对象属性的语法是:对象名称.属性名称
访问对象方法的语法是:对象名称.方法名称()
创建 JavaScript 对象
通过 JavaScript,您能够定义并创建自己的对象。
创建新对象有两种不同的方法:
使用 Object 定义并创建对象的实例。
使用函数来定义对象,然后创建新的对象实例。
使用 Object
在JavaScript中,几乎所有的对象都是Object类型的实例,它们都会从Object.prototype继承属性和方法。
Object 构造函数,会根据给定的参数创建对象,具体有以下情况:
如果给定值是 null 或 undefined,将会创建并返回一个空对象。
如果传进去的是一个基本类型的值,则会构造其包装类型的对象。
如果传进去的是引用类型的值,仍然会返回这个值,经他们复制的变量保有和源对象相同的引用地址。
当以非构造函数形式被调用时,Object 的行为等同于 new Object()。
语法格式:
new Object([value])
value 可以是任何值。
以下实例使用 Object 生成布尔对象:
var o = new Object(true);
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<script>
var person=new Object();
person.firstname="John";
person.lastname="Doe";
person.age=50;
person.eyecolor="blue";
document.write(person.firstname + " is " + person.age + " years old.");
</script>
</body>
</html>
也可以使用对象字面量来创建对象,语法格式如下:
{ name1 : value1, name2 : value2,...nameN : valueN }
其实就是大括号里面创建 name:value 对,然后 name:value 对之间以逗号 , 隔开。
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<script>
person={firstname:"John",lastname:"Doe",age:50,eyecolor:"blue"}
document.write(person.firstname + " is " + person.age + " years old.");
</script>
</body>
</html>
JavaScript 对象就是一个 name:value 集合。
使用对象构造器
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<script>
function person(firstname,lastname,age,eyecolor){
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.eyecolor=eyecolor;
}
myFather=new person("John","Doe",50,"blue");
document.write(myFather.firstname + " is " + myFather.age + " years old.");
</script>
</body>
</html>
在JavaScript中,this通常指向的是我们正在执行的函数本身,或者是指向该函数所属的对象(运行时)
一旦您有了对象构造器,就可以创建新的对象实例,就像这样:
var myFather=new person("John","Doe",50,"blue");
var myMother=new person("Sally","Rally",48,"green");
JavaScript for...in 循环
JavaScript for...in 语句循环遍历对象的属性。
语法
for (variable in object){
执行的代码……
}
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>点击下面的按钮,循环遍历对象 "person" 的属性。</p>
<button onclick="myFunction()">点击这里</button>
<p id="demo"></p>
<script>
function myFunction(){
var x;
var txt="";
var person={fname:"Bill",lname:"Gates",age:56};
for (x in person){
txt=txt + person[x];
}
document.getElementById("demo").innerHTML=txt;
}
</script>
</body>
</html>
JavaScript 的对象是可变的
对象是可变的,它们是通过引用来传递的。
以下实例的 person 对象不会创建副本:
var x = person; // 不会创建 person 的副本,是引用
如果修改 x ,person 的属性也会改变:
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wangxing</title>
</head>
<body>
<p>JavaScript 对象是可变的。</p>
<p>拷贝的对象改变来,原始的也会跟着改变。</p>
<p id="demo"></p>
<script>
var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}
var x = person;
x.age = 10;
document.getElementById("demo").innerHTML =
person.firstName + " is " + person.age + " years old.";
</script>
</body>
</html>
new 和不 new的区别:
如果 new 了函数内的 this 会指向当前这个 person 并且就算函数内部不 return 也会返回一个对象。
如果不 new 的话函数内的 this 指向的是 window。
2.2JavaScript Number 对象
JavaScript 只有一种数字类型。可以使用也可以不使用小数点来书写数字。
JavaScript 数字
JavaScript 数字可以使用也可以不使用小数点来书写:
var pi=3.14; // 使用小数点
var x=34; // 不使用小数点
极大或极小的数字可通过科学(指数)计数法来写:
var y=123e5; // 12300000
var z=123e-5; // 0.00123
所有 JavaScript 数字均为 64 位
JavaScript 不是类型语言。与许多其他编程语言不同,JavaScript 不定义不同类型的数字,比如整数、短整数、长整数、浮点等等。
在JavaScript中,数字不分为整数类型和浮点型类型,所有的数字都是由浮点型类型。JavaScript 采用 IEEE754 标准定义的 64 位浮点格式表示数字,它能表示最大值(Number.MAX_VALUE)为 ±1.7976931348623157e+308,最小值(Number.MIN_VALUE)为 ±5e-324。
此格式用 64 位存储数值,其中 0 到 51 存储数字(片段),52 到 62 存储指数,63 位存储符号:
值 (aka Fraction/Mantissa) | 指数(Exponent) | 符号(Sign) |
52 bits (0 - 51) | 11 bits (52 - 62) | 1 bit (63) |
精度
整数(不使用小数点或指数计数法)最多为 15 位。
var x = 999999999999999; // x 为 999999999999999
var y = 9999999999999999; // y 为 10000000000000000
小数的最大位数是 17,但是浮点运算并不总是 100% 准确:
var x = 0.2+0.1; // 输出结果为 0.30000000000000004
八进制和十六进制
如果前缀为 0,则 JavaScript 会把数值常量解释为八进制数,如果前缀为 0 和 "x",则解释为十六进制数。
var y = 0377;
var z = 0xFF;
绝不要在数字前面写零,除非您需要进行八进制转换。
默认情况下,JavaScript 数字为十进制显示。
但是你可以使用 toString() 方法 输出16进制、8进制、2进制。
var myNumber=128;
myNumber.toString(16); // 返回 80
myNumber.toString(8); // 返回 200
myNumber.toString(2); // 返回 10000000
无穷大(Infinity)
当数字运算结果超过了JavaScript所能表示的数字上限(溢出),结果为一个特殊的无穷大(infinity)值,在JavaScript中以Infinity表示。同样地,当负数的值超过了JavaScript所能表示的负数范围,结果为负无穷大,在JavaScript中以-Infinity表示。无穷大值的行为特性和我们所期望的是一致的:基于它们的加、减、乘和除运算结果还是无穷大(当然还保留它们的正负号)。
myNumber=2;
while (myNumber!=Infinity){
myNumber=myNumber*myNumber; // 重复计算直到 myNumber 等于 Infinity
}
除以0也产生了无限:
var x = 2/0;
var y = -2/0;
NaN - 非数字值
NaN 属性是代表非数字值的特殊值。该属性用于指示某个值不是数字。可以把 Number 对象设置为该值,来指示其不是数字值。
你可以使用 isNaN() 全局函数来判断一个值是否是 NaN 值。
var x = 1000 / "Apple";
isNaN(x); // 返回 true
var y = 100 / "1000";
isNaN(y); // 返回 false
除以0是无穷大,无穷大是一个数字:
var x = 1000 / 0;
isNaN(x); // 返回 false
数字可以是数字或者对象
数字可以私有数据进行初始化,就像 x = 123;
JavaScript 数字对象初始化数据, var y = new Number(123);
var x = 123;
var y = new Number(123);
typeof(x) // 返回 Number
typeof(y) // 返回 Object
实例
var x = 123;
var y = new Number(123);
(x === y) // 为 false,因为 x 是一个数字,y 是一个对象
Number 属性
属性 | 描述 |
Number.MAX_VALUE | 最大值 |
Number.MIN_VALUE | 最小值 |
Number.NaN | 非数字 |
Number.NEGATIVE_INFINITY | 负无穷,在溢出时返回 |
Number.POSITIVE_INFINITY | 正无穷,在溢出时返回 |
Number.EPSILON | 表示 1 和比最接近 1 且大于 1 的最小 Number 之间的差别 |
Number.MIN_SAFE_INTEGER | 最小安全整数。 |
Number.MAX_SAFE_INTEGER | 最大安全整数。 |
数字方法
方法 | 描述 |
Number.parseFloat() | 将字符串转换成浮点数,和全局方法 parseFloat() 作用一致。 |
Number.parseInt() | 将字符串转换成整型数字,和全局方法 parseInt() 作用一致。 |
Number.isFinite() | 判断传递的参数是否为有限数字。 |
Number.isInteger() | 判断传递的参数是否为整数。 |
Number.isNaN() | 判断传递的参数是否为 isNaN()。 |
Number.isSafeInteger() | 判断传递的参数是否为安全整数。 |
数字类型原型上的一些方法
方法 | 描述 |
toExponential() | 返回一个数字的指数形式的字符串,如:1.23e+2 |
toFixed() | 返回指定小数位数的表示形式。 var a=123; b=a.toFixed(2); // b="123.00" |
toPrecision() | 返回一个指定精度的数字。如下例子中,a=123 中,3会由于精度限制消失: var a=123; b=a.toPrecision(2); // b="1.2e+2" |