Object对象
------- 万物皆对象
Object类型,我们也称为一个
对象
。是JavaScript中的引用数据类型
。
- 它是一种
复合值
,它将很多值聚合到一起,可以通过名字访问这些值。 - 对象也可以看做是属性的无序集合,每个属性都是一个名/值对。
- 对象除了可以创建自有属性,还可以通过从一个名为原型的对象那里继承属性。
- 除了
字符串
、数字
、true
、false
、null
和undefined
之外,JS中的值都是对象。
创建对象
对象是一种 用来封装 属性 和 方法 的数据类型
- 方式一:
- 对象字面值:是封闭在花括号对 {} 中 0个或多个
键:值
无序列表 键
:属性名
值
:属性值
,可以是任意类型的值(数值类型、字符串类型、布尔类型、函数类型)- 特点
- 将数据包括在 大括号 中;
- 对象中以逗号分隔键值对;
- 用冒号分隔属性名和属性值;
- 不要忘记最后大括号后的分号;
let stuObj = {
usrName : 'james',
usrAge : 18,
usrGender : true,
sayHi : function(){
console.log('Hi,大家好啊~~!我是 ' + stuObj.usrName + ',年龄 '+ stuObj.usrAge);
}
};
- 方式二(new关键字):
//创建一个空对象
let stuObj = new Object();
//带初始值的对象
let stuObj = new Object( { usrName : 'james' , usrAge : 18 , usrGender : true } );
- 给对象赋值,添加属性
语法:
对象名.属性名 = 属性值;
let student=new Object();
student.name='小明';
student.age=18;
student.speak=function(){
console.log('I can speak English');
}
获取对象中的成员
- 利用点语法
console.log(strObj.name);
console.log(str.age);
- 利用[key]来获取
- key指的是对象的成员名字: name age…
console.log(strObj['name']);
console.log(strObj['age']);
- 遍历对象(for…in方法)
语法:key —>对象中成员的名字
for(let key in obj) {
obj[key];
}
- 判断对象中的数组并遍历
- typeof无法验证对象数组的类型
instanceof +数据类型:来判断数据是否成立
// console.log(guoObj.size instanceof Array);//true
// console.log(guoObj.size instanceof Array);//false
<script>
let stuObj=new Object();
stuObj.name='李雷';
stuObj.age='男';
stuObj.size=[1,2,3,4,5,6,7,8,9,10];
stuObj.hmm={};
stuObj.sayHi=function(){
console.log('hello world');
}
// 遍历对象
for(let key in stuObj){
// 如果成立,则代表当前的成员是数组类型
if(stuObj[key] instanceof Array){
for(let i = 0;i < stuObj[key].length;i++) {
// stuObj[key]---->数组的名称
console.log(stuObj[key][i]);
}
}
}
</script>
this关键字
对象方法中的 this 一般情况 代表
方法所在的对象
let stuObj = {
usrName : 'james',
usrAge : 18,
sayHi : function(){
console.log('Hi,大家好啊~~!我是 ' + this.usrName + ',年龄 '+ this.usrAge);
}
};
//调用 对象中的方法
stuObj.sayHi(); // Hi,大家好啊~~!我是 小白 ,年龄 21
- 本质:this 就是方法内部的一个系统级的 “变量”,用来保存方法调用时所属 对象 的 内存地址
- 口诀:谁调用,就是谁。谁调用方法,那么方法里的 this 就是谁!
- 简单的说:调用时哪个对象实例 . 出方法,那这个方法里的 this 就是哪个对象实例
值类型和引用类型
数据类型:简单数据类型(值类型)和复杂数据类型(引用数据类型)
值类型
(也叫简单数据类型
):string
,number
,boolean
,undefined
,null
- 值类型变量 的 数据 直接存放在变量(
栈
空间) - 基本数据类型的值是无法修改的,是不可变的。
- 基本数据类型的比较是值的比较,也就是只要两个
变量的值相等,我们就认为这两个变量相等。
- 值类型变量 的 数据 直接存放在变量(
引用类型
(也叫复杂数据类型
):通过 new 关键字创建的对象(系统对象、自定义对象)- 引用类型变量(栈空间)里存放的是地址,真正的 对象实例 存放在
堆
空间中 - 当一个变量是一个对象时,实际上变量中保存的并不是
对象本身,而是对象的引用。 - 当从一个变量向另一个变量复制引用类型的值时,会将
对象的引用复制到变量中,并不是创建一个新的对象。 - 这时,两个变量指向的是同一个对象。因此,改变其中
一个变量会影响另一个。
- 引用类型变量(栈空间)里存放的是地址,真正的 对象实例 存放在
函数
函数是由一连串的子程序(语句的集合)所组成的,可以被外部程序调用。向函数传递参数之后,函数可以返回一定的值。
函数的声明
首先明确一点
函数
也是一个对象
,所以函数也是在堆内存
中保存的。
- 语法
function 函数名(形参) {
函数体代码;
只要调用函数,就会执行这里面的代码;
}
函数中的实参与形参
形参
: 形式参数-----> 声明函数时的参数,就称为形参
实参
: 实际参数-----> 调用函数时的参数,就称为实参
- JS中的所有的参数传递都是按值传递的。
也就是说把函数外部的值赋值给函数内部
的参数,就和把值从一个变量赋值给另一
个变量是一样的。
function fun(a,b) {
// a,b就是形式参数
// a,b本质上就是变量
// a,b明明没有声明,为什么会是一个变量
// console.log(a,b);// undefined undefined:有声明,没有赋值
// 形参的声明,函数内部已经做好了,不需要程序员手动声明形参
// 调用传参的过程,其实就是把实参的值赋值给形参
// a = num1;
// b = num2;
console.log(a,b);
}
let num1 = 10,num2 = 20;
fun(num1,num2);
// num1 和 num2 就是实参
函数的调用
调用函数时,传递给函数的参数称为实参
(实际参数)
function getSum(a,b){
return a+b;
}
let result=getSum(123,456);
这样表示调用getSum这个函数,并将123和456作为实参传递给函数,函数中会将两个参数求和并赋值给result。
- 案例
设计一个函数,获得数组中最大值
思路:假设数组第一个为最大值,让其依次与数组中的其它元素比较
function getMaxOfArray(arr) {
let max = arr[0];
for(let i = 1;i < arr.length;i++) {
max = max > arr[i] ? max : arr[i];
}
console.log('数组中的最大值是:'+max);
}
let arr1 = [1,2,3,4,5,6,7,8,9,10];
let arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
getMaxOfArray(arr1);
getMaxOfArray(arr2);
函数的返回值
前提: 函数一定有返回值
返回值: 调用函数的时候,会返回给你一个值,这个值可以用变量保存起来
函数
默认的返回值
就是undefined
(有什么没赋值)
- return的作用:
- 作为一个返回值工具(把函数中的某一个值,返回到函数外)
- 用来打断程序的运行
// 1. 函数默认的返回值就是undefined
// function fun1() {
// console.log('啊,我是fun1我被调用了');
// }
// let str1 = '锅锅';
// console.log(str1);
// str1 = fun1();
// console.log(str1);
// 2. 函数中带有return关键字的情况
// 2.1 return后面带有某段代码(式子,变量.....),指的是与return在同一行(分号前)
function fun2(a,b) {
let sum = a + b;
return sum;
}
let str2 = fun2(10,20);
console.log(str2);
// 2.2 只有return,后面没有任何东西
// 返回的依旧是undefined
function fun3(a,b) {
let sum = a + b;
return;
}
let str3 = fun3(10,20);
console.log(str3);
// 2.3 带有return,但是后面还有代码
function fun4(a,b) {
let sum = a + b;
return;
// 有任何的代码在return之后,都不会被执行
console.log(sum);
}
let str4 = fun4();
console.log(str4);
- 案例:
设计一个函数判断用户是否成年
<script>
// 判断用户是否成年,返回结果
function isAdult(num) {
if (num >= 18) {
return '已成年';
}else {
return '未成年';
}
}
let age = prompt('请输入你的年龄:');
console.log('你是一个'+isAdult(age));;
</script>
匿名函数
匿名函数就是没有名字的函数
匿名函数的声明
(
function () {
console.log('我是一个匿名函数');
}
)
匿名函数的调用
- 将匿名函数赋值给一个变量
let fun2 = function () {
console.log('我是一个匿名函数');
}
fun2();
- 匿名函数自调用-----> 在匿名函数后+();
(
function () {
console.log('我是一个匿名函数');
}
)();
(
function (userName) {
console.log('我是一个好人,我的名字叫'+userName);
}
)('张三');
- 不规则写法
(
function () {
console.log('我是一个匿名函数');
}()
)
案例:
以函数的方式写ATM练习
思路:先从简单功能开始实现
<script>
// 本金
let money = 1000;
// 用户输入序号
let userInput;
// 修改余额变量
let tempmoney;
// 开关
let flag;
function main() {
do {
// 用户输入操作
userInput = +prompt('请输入您要的操作:\r1.存钱\r2.取钱\r3.显示余额\r4.退出');
if (userInput == 4) {
// 4.退出
alert('喜欢,您再来!');
break;
} else if (userInput == 1) {
// 1.存钱
moneyIn();
} else if (userInput == 2) {
// 2.取钱
moneyOut();
} else if (userInput == 3) {
// 3.显示余额
showMoney();
}
} while (true);
}
// 封装功能函数
// 显示余额
function showMoney() {
alert('您的余额是:' + money + '元');
}
// 存钱
function moneyIn() {
tempmoney = +prompt('请输入您的金额:');
flag = moneyIsOk(tempmoney);
if (flag == false) {
// 验证失败进入
alert('请输入正确的金额');
moneyIn(); //自己调用自己
return;
}
money += tempmoney;
showMoney();
}
// 取钱
function moneyOut() {
tempmoney = +prompt('请输入您的金额:');
flag = moneyIsOk(tempmoney);
if (flag == false) {
// 验证失败进入
alert('请输入正确的金额');
moneyOut(); //自己调用自己
return;
}
money -= tempmoney;
showMoney();
}
// 判断金额
function moneyIsOk(num) {
if (num < 100 || num % 100 != 0) {
return false;
}
}
main();
</script>
arguments
arguments本身是一个数组,保存的调用是传入的参数,在函数外使用会报错
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 设计一个函数: 用来求传入的参数的和
// 要求: 不限制传入参数个数
// function getSum(a,b) {
// let sum = a + b;
// return sum;
// }
// console.log(getSum(10,20));
// 函数中的一个属性:arguments
// console.log(arguments);// 在函数外使用会报错
// function fun() {
// console.log(arguments);
// // arguments本身是一个数组,保存的调用是传入的参数
// }
// fun(10,20,30,40,50);
function getSum() {
let sum = 0;
// 遍历参数数组,求累加和
for(let i = 0;i < arguments.length;i++) {
sum += arguments[i];
}
return sum;
}
console.log(getSum(10,20));
console.log(getSum(10,20,30));
console.log(getSum(10,20,30,40));
console.log(getSum(10,20,30,40,50));
</script>
</body>
</html>
作用域
变量起作用的区域
全局作用域
: 函数外的区域,全局作用域
在全局作用域中声明的变量,就是全局变量,在程序的任何位置都可以使用
let str1 = '学生1';
console.log(str1);
function fun1() {
// 函数内
console.log(str1);
}
fun1();
局部作用域
: 函数内部的区域,局部作用域
在局部作用域中声明的变量,就是局部变量,只能在当前局部作用域使用
function fun2() {
let str2 = '学生2';
console.log(str2);
}
fun2();
console.log(str2);//str2 is not defined
- 块级作用域: 在{}内的都是块级作用域
在块级作用域中声明的变量,只能在当前块级作用域使用
{
let str3 = '学生3';
console.log(str3);
}
console.log(str3);//str2 is not defined