JS基础(三)-函数、JS中的对象
函数
- 函数基本概念
- JavaScript中函数的概念和C语言几乎一样,都是用于封装一段代码,方便将来重复使用的
- 不同的是JavaScript中的函数也是一种类型, 是引用类型
-
函数的定义
// 格式一: function 函数名(形参1, 形参2, 形参3...) { //函数体 return 返回值; } // 格式二: var 变量 = function(实参1, 实参2, 实参3...){ //函数体 return 返回值; };
- 注意点:
- 和C语言一样, 函数可以没有形参, 也可以有一个或多个形参
- 不同的是由于JavaScript是弱语言, 所以形参只用写一个占位符即可
- 和C语言一样, 函数可以没有返回值, 也可以有返回值
- 不同的是JavaScript是弱语言, 所以不用写返回值类型
- 如果函数没有使用 return语句 ,那么函数有默认的返回值:undefined
- 如果函数使用 return语句,那么return后面的值,就成了函数的返回值
- 如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined
function sayHi(name) { console.log(name); } sayHi("sss"); var sayHello = function (name, age) { console.log("name = "+ name, "age = "+age); } sayHello("sss", 12);s function sum1(a, b) { var res = a + b; return res; } var res = sum1(10, 20); console.log(res); // 30 function sum2(a, b) { var res = a + b; return; } var res = sum2(10, 20); console.log(res); // undefined function sum3(a, b) { var res = a + b; } var res = sum3(10, 20); console.log(res); // undefined
- 注意点:
- arguments的使用
-
由于JavaScript中的函数是引用类型(可以添加属性和方法)。所以所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有的实参。arguments是一个伪数组,因此可以进行遍历
function getSum() { var sum = 0; for (var i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; } var sum = getSum(5, 1, 3, 4); console.log(sum);
-
- 函数作为参数和返回值
- 由于JavaScript中的函数也是一种数据类型, 所以函数也可以作为参数和返回值使用
-
函数作为其他函数参数
var sayHi = function () { console.log("hello world"); } function test(fn) { fn(); } test(sayHi);
-
函数作为其他函数返回值
function test() { var sayHi = function () { console.log("hello world"); } return sayHi } var res = test(); res();
- 匿名函数
- 没有名称的函数, 我们称之为匿名函数
- 匿名函数不能单独出现, 一般作为其他函数参数或者返回值使用
// 报错 function () { console.log("hello world"); } // 立即执行函数 (function () { console.log("hello world"); })(); // 作为函数参数 function test(fn) { fn(); } test(function () { console.log("hello world"); }); // 作为函数返回值 function test() { return function () { console.log("hello world"); } } var res = test(); res();
ES6新增语法
- 扩展运算符在函数的形参列表中的作用
-
将传递给函数的所有实参打包到一个数组中
//values打包所有的实参 function getsum(...values){ console.log(values) var sum = 0; for (var i = 0; i < values.length; i++) { sum += values[i]; } return sum; } getsum(10,20);
-
注意: 扩展运算符只能写在最后
//只能写在最后 function getsum(a,...values){}
-
-
函数形参默认值
function sum(a = 10,b= 6){ return a + b; } console.log(sum());
- 箭头函数
-
ES6新增的一种定义函数的方法,简化定义函数
let 函数名称 = (形参列表)=>{ 函数体 }
-
如果只有一个形参,形参的括号可以省略
let 函数名称 = 形参1=>{ 函数体 }
-
如果
{}
中的函数体只有一句代码,则{}
可以省略// 箭头函数 let sum = (a,b)=>{ return a + b; } console.log(sum(10,20)); // 省略() let say = name => { console.log("hello" + name); } // 省略{} let say2 = name => console.log("hello" + name);
-
作用域
- JavaScript中作用域的概念和C语言一样, 也分为全局作用域和局部作用域
- 全局作用域
- 在任何地方都可以访问到的就是全局作用域
- 在script标签中或一个独立js文件中定义的就是全局作用域
- 局部作用域
- 只在固定的代码片段内可访问到的变量,例如函数内部。对应局部作用域(函数作用域)
- 写在函数内部的都是局部作用域, 只能在当前函数内访问
- 注意点:
- 如果在函数中定义变量时,如果不添加var关键字, 这个变量是一个全局变量
- 块级作用域:
- 任何一对花括号
{}
中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。 - 在ES5之前没有块级作用域的的概念,只有函数作用域,现阶段可以认为JavaScript没有块级作用域
- 在JS中,ES6之前(变量用var修饰),在块级作用域中定义的变量,是全局变量;在ES6之后(用let修饰),在块级作用域中定义的变量,外部不能访问
- if、while、do都是块级作用域
- 任何一对花括号
<script> //1.全局变量 var num = 10; // 该变量是全局作用域 function test() { // 在函数中访问全局作用域num变量 console.log("test中"+num); } test(); // 在外面访问全局作用域num变量 console.log("外部"+num); //2. 全局函数 function test() { // 该函数是全局作用域 console.log("test函数"); } // 在外面访问全局作用域test函数 test(); function demo() { // 在函数中访问全局作用域test函数 test(); } demo(); //3. 局部变量 function test() { var num = 123; // 该变量是局部作用域 // 可以在同一个局部作用域中访问 console.log("test中"+ num); } // 不能在局部范围以外访问 console.log("外部"+num); function test() { //4. 局部函数 function demo() { // 该函数是局部作用域 console.log("demo函数"); } // 可以在同一个局部作用域中访问 demo(); } // 不能在局部范围以外访问 demo(); </script> //注意点 <script> function test() { // 企业开发千万不要这么写 num = 123; console.log(num); } test(); console.log(num); </script> //块级作用域 { var a = 10; } // 10,用var修饰,即ES6之前,则a为全局作用域 console.log(a); // 但是如果用了let,即ES6,那么块作用域外就不能访问到 { let b = 10; } // 报错 console.log(b);
预解析
- JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的。
- JavaScript解析器执行JavaScript代码的时候,分为两个过程:
- 预解析过程
- 代码执行过程
- 预解析过程:
- 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
- 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
- 先提升var,再提升function。
-
举例
//变量预解析 console.log(num); // undefined var num = 123; //函数解析 test(); function test() { console.log("hello world"); }
- 注意点:
-
变量和函数同名时, 函数的优先级高
console.log(num); function num() { console.log("hello world"); } var num = 666; console.log(num); /* //预解析后: function num() { console.log("hello world"); } var num; console.log(num); num = 666; console.log(num); */
-
不同方式定义函数区别
-
预解析时提升的方式不同
// 1.函数声明 test(); function test() { console.log("xx学院"); } // 2.函数表达式 demo(); // 报错 var demo = function () { console.log("xxxxx"); } /* //预解析后 function test() { console.log("xx学院"); } var demo; test(); demo(); demo = function () { console.log("xxxxx"); }
-
新旧版本浏览器预解析处理方式不同
/* 在新版本浏览器中, 代码块中的函数不会被提升 在旧版本浏览器中, 代码块中的函数会被提升 新版本输出"123" 老版本输出"456" */ if(true){ function test() { console.log("123"); } }else{ function test() { console.log("456"); } } test();
-
-
JS中的对象
- 什么是对象?
- 在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、 函数等。
- 对象是由属性和方法组成的。
- 创建对象的三种方式
- 在 JavaScript 中,现阶段我们可以采用三种方式创建对象(object):
- 利用字面量创建对象
- 利用 new Object 创建对象
- 利用构造函数创建对象
- 在 JavaScript 中,现阶段我们可以采用三种方式创建对象(object):
创建对象的三种方式
1. 利用字面量创建对象
- 对象字面量:就是花括号
{ }
里面包含了表达这个具体事物(对象)的属性和方法。 { }
里面采取键值对的形式表示- 键:相当于属性名
- 值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)
- 对象的调用
- 对象里面的属性调用 :
对象.属性名
- 对象里面属性的另一种调用方式 :
对象[‘属性名’]
,注意方括号里面的属性必须加引号 - 对象里面的方法调用:
对象.方法名()
,注意这个方法名字后面一定加括号
- 对象里面的属性调用 :
-
代码举例:
// 1.使用字面量创建对象 var obj = {}; // 相当于var obj = new Object() // 2.动态给空对象新增属性 obj.name = "lnj"; obj.age = 33; // 3.动态给空对象新增方法 obj.say = function () { console.log("hello"); } var star = { name : 'pink', age : 18, sex : '男', sayHi : function(){ alert('大家好啊~'); } }; //调用 // 调用名字属性 console.log(star.name); // 调用名字属性 console.log(star['name']); // 调用 sayHi 方法,注意,一定不要忘记带后面的括号 star.sayHi();
- 变量、属性、函数、方法总结
- 变量:单独声明赋值,单独存在
- 属性:对象里面的变量称为属性,不需要声明,用来描述该对象的特征
- 函数:单独存在的,通过“函数名()”的方式就可以调用
- 方法:对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用,方法 的行为和功能。
2. 利用new Object创建对象
- Object() :第一个字母大写
- new Object() :需要 new 关键字
-
使用的格式:
对象.属性 = 值;
// 1.使用默认类创建一个空对象 var obj = new Object() // 2.动态给空对象新增属性 obj.name = "xx"; obj.age = 33; // 3.动态给空对象新增方法 obj.say = function () { console.log("hello"); } // 4.使用对象的属性和方法 console.log(obj.name); console.log(obj.age); obj.say();
3. 利用构造函数创建对象
- 构造函数 :是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
- 在 js 中,使用构造函数要时要注意以下两点:
- 构造函数用于创建某一类对象,其首字母要大写
- 构造函数要和new一起使用才有意义
- 注意:
- 构造函数约定首字母大写。
- 函数内的属性和方法前面需要添加this ,表示当前对象的属性和方法。
- 构造函数中不需要 return 返回结果。
- 当我们创建对象的时候,必须用 new 来调用构造函数。
function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.sayHi = function() { alert('我的名字叫:' + this.name + ',年龄:' + this.age + ',性别:' + this.sex); } } var bigbai = new Person('大白', 100, '男'); var smallbai = new Person('小白', 21, '男'); console.log(bigbai.name); console.log(smallbai.name);
- 构造函数和对象
- 构造函数,如 Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)
- 创建对象,如 new Stars(),特指某一个,通过 new 关键字创建对象的过程我们也称为对象实例化
- new关键字
- new 在执行时会做四件事情:
- 在内存中创建一个新的空对象。
- 让 this 指向这个新的对象。
- 执行构造函数里面的代码,给这个新对象添加属性和方法。
- 返回这个新对象(所以构造函数里面不需要return)。
- new 在执行时会做四件事情:
遍历对象属性
for...in
语句用于对数组或者对象的属性进行循环操作。-
其语法如下:
for (变量 in 对象名字) { // 在此执行代码 }
-
语法中的变量是自定义的,它需要符合命名规范,通常我们会将这个变量写为 k 或者 key。
for (var k in obj) { console.log(k); // 这里的 k 是属性名 console.log(obj[k]); // 这里的 obj[k] 是属性值 }
JS 内置对象
- 内置对象
- JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象
- 前面两种对象是JS基础内容,属于 ECMAScript; 第三个浏览器对象属于我们JS独有的, 我们JS API 讲解
- 内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
- 内置对象最大的优点就是帮助我们快速开发
- JavaScript 提供了多个内置对象:Math、 Date 、Array、String等
- 查文档
- 学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN/W3C 来查询。
- Mozilla 开发者网络(MDN)提供了有关开放网络技术(Open Web)的信息,包括 HTML、CSS 和万维网及 HTML5 应用的 API。
- MDN:https://developer.mozilla.org/zh-CN/
Math 对象
- Math 概述
-
Math 对象不是构造函数,它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值 等)可以使用Math中的成员。
Math.PI // 圆周率 Math.floor() // 向下取整 Math.ceil() // 向上取整 Math.round() // 四舍五入版 就近取整 注意 -3.5 结果是-3 Math.abs() // 绝对值 Math.max()/Math.min() // 求最大和最小值
-
- 随机数方法 random()
- random() 方法可以随机返回一个小数,其取值范围是
[0,1)
,左闭右开0 <= x < 1random()
方法可以随机返回一个小数,其取值范围是[0,1)
,左闭右开0 <= x < 1
-
得到一个两数之间的随机整数,包括两个数在内
function getRandom(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
- random() 方法可以随机返回一个小数,其取值范围是
日期对象
- Date概述
- Date对象和Math对象不一样,他是一个构造函数,所以我们需要实例化后才能使用
- Date实例用来处理日期和时间
- Date()方法的使用
-
获取当前时间必须实例化
var now = new Date(); console.log(now);
-
Date() 构造函数的参数
- 如果括号里面有时间,就返回参数里面的时间。例如日期格式字符串为‘2019-5-1’,可以写成
new Date('2019-5-1')
或者new Date('2019/5/1')
- 如果Date()不写参数,就返回当前时间
- 如果Date()里面写参数,就返回括号里面输入的时间
- 如果括号里面有时间,就返回参数里面的时间。例如日期格式字符串为‘2019-5-1’,可以写成
-
- 日期格式化
- 我们想要
2019-8-8 8:8:8
格式的日期,要怎么办? -
需要获取日期指定的部分,所以我们要手动的得到这种格式。
getFullYear() //获取当前年 getMonth() //获取当前月份(0-11) getDate() //获取当前日期 getDay() //获取当前天(周日0-6周六) getHours() //获取当前小时 getMinutes() //获取当前分钟 getSeconds() //获取当前秒
- 我们想要
- 获取日期的总的毫秒形式
- Date 对象是基于1970年1月1日(世界标准时间)起的毫秒数
-
我们经常利用总的毫秒数来计算时间,因为它更精确
// 实例化Date对象 var now = new Date(); // 1. 用于获取对象的原始值 console.log(date.valueOf()) console.log(date.getTime()) // 2. 简单写可以这么做 var now = + new Date(); // 3. HTML5中提供的方法,有兼容性问题 var now = Date.now();
数组对象(略)
数字符串对象
- 根据字符返回位置
- 字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。
indexOf('要查找的字符串',开始的位置): 返回指定内容在原字符串中的位置,如果找不到就返回-1,开始的位置是index索引号 lastindexOf:从后往前找,只找第一个匹配的
-
根据位置返回字符(重点)
charAt(index): 返回指定位置的字符串 charCodeAt(index): 获取指定位置处字符串的ASCII str[index]:获取指定位置字符串,H5、IE8+支持,跟charAt等效
-
字符串操作方法(重点)
contact(str1,str2...): 用于连接两个或者多个字符串,等效于+ substr(start,length): 从start位置开始,length取的个数 slice(start,end):从start位置开始截取到end位置,end取不到。start、end都是索引 substring(start,end):从start位置开始截取到end位置,end取不到,与slice区别,这个方法不接受负值
- replace()方法
- replace() 方法用于在字符串中用一些字符替换另一些字符。
-
其使用格式如下:
replace(被替换的字符串, 要替换为的字符串);
- split()方法
-
split()方法用于切分字符串,它可以将字符串切分为数组。在切分完毕之后,返回的是一个新数组。
var str = 'a,b,c,d'; console.log(str.split(','));// 返回的是一个数组 [a, b, c, d]
-