JavaScript基础(三)

JavaScript基础(三)

函数

概述

函数:就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。 封装:把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。

函数的声明与调用

// 声明
function funcName(params) {
    // function statements
}
funcName(params);
// 调用

形参与实参

声明时传入的为形参,调用时传入的为实参。

实参个数与形参个数不匹配的情况

参数个数说明
形参和实参个数相等输出正确结果
实参个数多于形参只取到形参的个数
实参个数少于形参多的形参定义为undefined,结果为NaN
function sum(num1, num2) {
    console.log(num1 + num2);
}
sum(100, 200); // 300, 形参和实参个数相等,输出正确结果
sum(100, 400, 500, 700); // 500, 实参个数多于形参,只取到形参的个数
sum(200); // NaN, 实参个数少于形参,多的形参定义为undefined,结果为NaN

在JavaScript中,形参的默认值是 undefined

声明函数的三种方法

function命令

function funcName(params) {
    // function statements
}

函数表达式

const funcName = function(params) {
    // function statements
}

箭头函数=>

创建一个函数更加简洁的方式,有两种方式:

  • 不带花括号:(...args) => expression,计算表达式,直接返回。
  • 带花括号:(...args) => { bodu },可以编写多行多个语句,需要 return 语句返回。
let sum = (a, b) => a + b;

Function构造函数

const add = new Function(
    'x',
    'y',
    return 'x + y'
);

注意

  • 函数未指定返回值则默认返回 undefined

arguments的使用

arguments 是所有JS函数内置的对象,但也只有函数具有。

function test() {
    return arguments;
}
console.log(test(1,2,3,4));

输出:

Arguments(4) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]

函数的 arguments 是一种伪数组:

  1. 具有数组的 length 属性
  2. 按照索引方式进行存储
  3. 没有真正数组的一些方法 pop()push()

数组

基本概念

  • JS 数组都是动态创建的,可以自由增加数组长度,这点不同于 C/C++。
  • 一个 JS 数组内可以存放不同类型的元素,例如 ['abc', 1, true, undefined],这点也不同于 C/C++/Java。

创建数组

数组字面量创建数组
  • 创建空数组

    let arr = [];
    
    
  • 创建一般数组

    let arr = [1, 2, 3];
    
    
new Array 创建数组对象
  1. 创建空数组

    let arr = new Array();
    
    
  2. 创建指定长度的数组,有2个空数组元素

    let arr1 = new Array(2);
    
    
  3. 创建放有指定元素的数组([2, 3])

    let arr2 = new Array(2, 3);
    
    
  4. 一些示例

    let arr_0 = [1, true, "aaa"];
    let arr_1 = [];
    let arr_2 = new Array(); // []
    let arr_3 = new Array(2); // [empty × 2]
    let arr_4 = new Array(2,); // [empty × 2]
    let arr_5 = new Array(2, 3, 4); // [2, 3, 4]
    
    

基本操作

  1. 数组元素访问

    let e = arr[index];
    
    
  2. 获取数组长度

    let len = arr.length;
    
    
  3. 数组遍历
    方式一:

    for (let i = 0; i < arr.length; i++) {
        console.log(arr[i]);
    }
    
    

    方式二:

    for (const i in arr) {
        console.log(arr[i]);
    }
    
    
  4. 数组逆转

    // 反转数组
    function reverse(arr) {
        let res = [];
        for (let i = arr.length - 1; i >= 0; i--) {
            res[res.length] = arr[i];
        }
        return res;
    }
    console.log(reverse([1, 2, 3, 4, 0])); // [0, 4, 3, 2,
    
    

检测一个值是否为数组

instanceof
function isArray(test) {
    if (test instanceof Array) return true;
    return false;
}
console.log(isArray([1, 2])); // true
console.log(isArray(1)); // false

Array.isArray[]

Array.isArray() 方法用于检测一个值是否为数组。

添加删除数组元素的方法

方法名说明返回值
push(arg1,...)末尾添加一个或多个元素返回新的长度
pop()删除数组最后一个元素,数组长度减 1,无参数,修改了原数组返回所删除元素的值
unshift()向数组的开头添加一个或多个元素,修改了原数组返回新的长度
shift()删除数组的第一个元素,数组长度减 1,无参数,修改了原数组返回第一个元素的值

数组排序

方法名说明是否修改原数组
reverse()颠倒数组中元素顺序,无参数会改变原数组,返回新数组
sort()对数组的元素进行排序会改变原数组,返回新数组

sort 方法对数组进行原地排序,但是默认按照字典序排序。需要传入一个比较函数 cmp(a, b),然后得到我们需要的排序效果。

let arr = [1, 4, 17, 12, 9];

arr.sort();
console.log(arr); // [ 1, 12, 17, 4, 9 ]

let cmp = (a, b) => a - b;

arr.sort(cmp);
console.log(arr); // [ 1, 4, 9, 12, 17 ]Copy to clipboardErrorCopied

其中,let cmp = (a, b) => a - b; 为升序,b - a 为降序。

数组索引方法

方法名说明返回值
indexOf()数组中查找指定元素的 第一个索引若存在则返回索引号,否则返回 -1
latsIndexOf()查找指定元素在数组中的 最后一个的索引若存在则返回索引号,否则返回 -1

indexOf 前面开始查找,lastIndexOf 从后面开始查找,但索引都是从前往后由 0 算起。

let arr = ['red', 'green', 'blue', 'pink', 'blue'];

console.log(arr.indexOf('blue')); // 2
console.log(arr.lastIndexOf('blue')); // 4
console.log(arr.indexOf('yellow')); // -1

数组去重

// 数组去重
function unique(arr) {
    let res = [];
    for (let i = 0; i < arr.length; i++) {
        if (res.indexOf(arr[i]) === -1) {
            res.push(arr[i]);
        }
    }
    return res;
}

console.log(unique([ 2, 3, 3, 4, 5, 5 ])); // [ 2, 3, 4, 5 ]


数组与字符串互转

数组转换为字符串
方法名说明返回值是否改变原数组
toString()将数组转换成字符串,逗号分隔每一个返回一个字符串不改变
join('分隔符')把数组中的所有元素转换为一个字符串,以指定符号分割返回一个字符串不改变

示例

let a = ['a', 'b', 'c', 'd', 'e'];

console.log(a.toString());  // a,b,c,d,e
console.log(a.join('')); // abcde
console.log(a.join('-')); // a-b-c-d-e
console.log(a); // [ 'a', 'b', 'c', 'd', 'e' ]

字符串转换为数组

使用 split() 方法。

let str = 'blue-green-pink-red';
let res = str.split('-');
console.log(res); // [ 'blue', 'green', 'pink', 'red' ]

作用域

作用域概述

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高 程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

全局变量

  • 在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
  • 全局变量在代码的任何位置都可以使用
  • 在全局作用域下var声明的变量是全局变量。
  • 特殊情况下,在函数内不使用var声明的变量也是全局变量(不建议使用)

局部变量

在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)

  • 局部变量只能在该函数内部使用
  • 在函数内部var声明的变量是局部变量
  • 函数的形参实际上就是局部变量

全局变量与局部变量区别

  • 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
  • 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间

var、let、const

ES6 以前,JS 没有块级作用域。ES6 新增 let const 之后才有了块级作用域。 块级作用域是指用 {} 包括起来的一段代码,例如 if 、while 等等。 函数作用域就是指变量只在函数内部起作用。

  • var 声明的是函数作用域的变量
  • let 声明的是块级作用域的变量
  • const 声明的是块级作用域的变量

作用域链

  • 只要是代码,就至少有一个作用域
  • 写在函数内部的局部作用域
  • 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
  • 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链

声明提升

  1. 我们js引擎运行js分为两步: 预解析,代码执行
    • 预解析js引擎会把js里面所有的var 还有function提升到当前作用域的最前面
    • 代码执行 按照代码书写的顺序从上往下执行
  2. 预解析分为变量预解析(变量提升) 和函数预解析(函数提升)
    • 变量提升就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作
    • 函数提升就是把所有的函数声明提升到当前的作用域最前面,不调用操作

举例一

func();
var func = function () {
    console.log('hello');
}
// 出错,以上代码相当于:
var func;
func();
func = function () {
    console.log('hello');
}

举例二

f1()
console.log(c);
console.log(b);
console.log(a);
function f1() {
    var a = b = c = 9;
    console.log(a);
    console.log(b);
    console.log(c);
}

相当于

function f1() {
    var a;
    c = 9;
    b = c;
    a = b;
    console.log(a);
    console.log(b);
    console.log(c); 
}
f1();
console.log(c);
console.log(b);
console.log(a);

输出

// answer
/*
9
9
9
9
9
error
*/

PREVIOUS

创建对象

对象

什么是对象?

在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。

对象是由属性和方法组成的。

  • 属性:事物的特征,在对象中用属性来表示(常用名词)
  • 方法:事物的行为,在对象中用方法来表示(常用动词)
为什么需要对象?

创建对象

  • 使用字面量创建对象
  • 使用 new Object 创建对象
  • 利用构造函数创建对象
字面量创建

使用 {} 创建,包含属性和方法,采用键值对表示,创建的对象称为对象字面量。

var obj = {
    uname: 'MurphyChen',
    age: 18,
    sayHi: function () {
        console.log('Hi!);
    }
}

使用对象的属性和方法
  1. 调用对象的属性
// 方法一
objectName.attrName
// 方法二
objectName['attrName'] // 不要忘记引号

  1. 调用对象的方法
objectName.funcName();//不要忘记括号

使用newObject创建对象

// 创建空对象
let obj = new Object();
//添加属性
obj.uname = 'MurphyChen';
obj.age = 18;
obj.sayHi = function() {
    console.log('Hi!');
}

利用构造函数创建对象

前两种创建对象的方法,每次都只能创建一个对象。但需要多个具有相同属性和方法的对象的时候,就需要使用构造函数来创建。

构造函数将相同的属性和方法封装在一个函数里。

构造函数语法

// 定义
function ConFuncName(params) {
    this.attr = value;
    this.methods = function() {};
}
// 调用
let obj = new ConFuncName(params);


  • 构造函数名单词首字母均大写
  • 函数不需要返回值

举例

function Star(uname, age, sex) {
    this.name = uname;
    this.age = age;
    this.sex = sex;
}
let ldh = new Star('刘德华', 18, '男');
let zxy = new Star('张学友', 19, '男');
console.log(typeof ldh); // object
console.log(ldh.sex); // 男
console.log(zxy.name); // 张学友
构造函数的实质

构造函数相当于创建了一个抽象的类,使用关键字 new 创建一个对象的过程称为类的实例化,对象是具体的。

new关键字的执行过程
  1. 在内存中创建一个空的对象;
  2. this 指向这个空对象;
  3. 执行构造函数里面的代码,给空对象添加属性和方法;
  4. 返回此对象。
遍历对象

for...in 可以对数组和对象进行遍历。

语法

for (const key in obj) {
    console.log(key); // 遍历属性名
    console.log(obj[key]); // 遍历属性值
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我想去拉萨。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值