【学习笔记】JavaScript基础 041-060

041 嵌套 for循环

例:输出金字塔

*
* *
* * *
* * * *
* * * * *

代码

for (let i = 0; i < 5; i++) {
    for (let j = 0; j <= i; j++) {
        document.write("*&nbsp;");
    }
    document.write("<br />");
}

042-043 for循环练习

练习:打印九九乘法表

<script>
    for (let i = 1; i <= 9; i++) {
        for (let j = 1; j <= i; j++) {
            document.write("<span>" + j + "*" + i + "=" + (j*i) + "</span>");
        }
        document.write("<br />")
    }
</script>
<style type="text/css">
    body {
        width: 2000px;
    }
    
    span{
        display: inline-block;
        width: 80px;
    }
</style>

练习:打印1-100间所有质数

for (let i = 2; i <= 100; i++) {
    let flag = true;
    let limit = Math.sqrt(i);
    for (let j = 2; j <= limit; j++) {
        if (i % j == 0) {
            flag = false;
            break;
        }
    }
    if (flag) {
        console.log(i);
    }
}

044 break 和 continue

break

break:跳出 switch 或循环;不能用于 if;立即终止所处的循环
跳出多重循环:可以先给循环体取名来标识当前循环

outer:
for (let i = 0; i < 5; i++) {
    console.log("@外层循环" + i);
    for (let j = 0; j < 5; j++) {
        break outer;
        console.log("内层循环:" + j);
    }
}

continue

continue:跳过本次循环,从循环体开始位置执行

性能测试

console.time("test");
// 执行的程序
console.timeEnd("test");

045 质数练习的改进

通过 Math.sqrt() 对一个数进行开方

046 对象简介

基本数据类型都是单一的值(如 "hello", 123, true),值与值之间没有联系
Object 对象,属于复合数据类型,在对象中可以保存多个不同数据类型的属性
对象的分类

  1. 内建对象
    • ES 标准定义的对象,任何的ES实现都可以使用
    • 例:Math, String, Number, Boolean, Function, Object...
  2. 宿主对象
    • JS 的运行环境提供的对象,主要指浏览器提供的对象
    • 例:BOM, DOM
  3. 自定义对象
    • 开发者自己创建的对象

047 对象的基本操作

创建对象

new 关键字调用的函数,是构造函数 constructor
构造函数是专门用于创建对象的函数
使用 typeof 检查对象会返回 object

let obj = new Object();

添加 / 修改属性

对象.属性名 = 值

obj.name = "Me";
obj.gender = "male";
obj.age = 18;

读取属性

对象.属性名

console.log(obj.name);
// console.log(name); 会报错

如果读取对象中没有的属性,不会报错,而是返回 undefined

删除属性

delete 对象.属性

delete obj.name;

048 属性名和属性值

属性名:不强制要求遵守标识符规范,但是尽量按照标识符
特殊属性名:需要用中括号,对象["属性名"] = 属性值

obj["123"] = "hello";

属性值:可以是任意数据类型(包括 Object,甚至可以是对象自己)
检测是否有属性:in 运算,检查一个对象中是否有指定属性

console.log("test" in obj);

049 基本数据类型和引用数据类型

基本数据类型:String, Number, Boolean, Null, Undefined
引用数据类型:Object

JS 基本数据类型直接在栈内存中,值与值独立存在,修改一个变量不会影响其他变量

let a = 123;
let b = a;
a++;
console.log(b);  // 123

引用数据存储在堆内存中,栈内存中保存的是内存地址(变量的引用),修改一个地址的变量会影响所有该地址的引用

let obj1 = {name : "123"};
let obj2 = obj;
obj1.name = "456";
console.log(obj2.name);    // 456
obj2 = null;               // 不影响 obj1

let obj3 = {name: "789"};
let obj4 = {name: "789"};
console.log(obj3 == obj4); // false

050 对象字面量

let obj = {
    name: "123",
    age: 28,
    gender: "male",
    test: {
        name: "456"
    }
};

属性名实际上是字符串,可以加引号,也可以不加(特殊属性名必须加字符串)
属性名和属性值是成对的,名和值之间用 : 连接

051 函数的简介

函数也是对象,一切东西都是对象
函数中可以封装一些功能(代码),在需要时可以执行
可以将要封装的代码以字符串形式传递给构造函数

Function 对象

let fun1 = new Function("alert('Hello world');");
console.log(typeof fun1);   // function

封装到函数的代码不会立即执行,在调用函数时才会执行

fun1();

函数声明

实际开发中很少使用 Function(),而是使用函数声明

function 函数名([形参1, 形参2,..., 形参n]) {
    代码
}

function fun2() {
    console.log("执行 fun2");
    alert("6");
    document.write("7");
}
fun2();

函数表达式

函数表达式会生成匿名函数

let fun3 = function() {
    alert("9");
}; // 注意这是赋值语句,所以要有分号

052 函数的参数

调用函数时,可以在()中指定实参,实参会赋值给函数中对应的形参

function sum(a, b) {
    console.log(a + b);
}

sum(1, 2);
sum(123, 456);

调用函数时不会检查实参类型,所以要注意非法输入

sum(123, "hello"); // 123hello

调用函数时也不会检查实参数量,多余的实参不会赋值,少的实参是 undefined;

sum(1, 2, 3);  // 1 + 2 -> 3 
sum(123);      // 123 + undefined -> NaN

053 函数的返回值

使用 return 设置函数返回值

function sum(a, b) {
    return a + b;
}
let result = sum(1, 2);
console.log(result);    // 3

return 后的语句都不会执行
return 后不跟任何值,或者函数无 return,则返回 undefined

let result = alert("6");
console.log(result);    // undefined

054 实参可以是任何值

实参可以是对象;参数过多时可以将参数封装到对象中

function sum(obj) {
    return obj["first"] + obj["second"];
}

实参可以是函数

function hello() {
    console.log("Hello");
}
function fun(a) {
    a();
}
fun(hello);
fun(function(){alert("6")});

注意函数对象与函数返回值的区别

fun(sum);    // 传的是函数对象
fun(sum());  // 传的是返回值

055 返回值的类型

返回值可以是任何类型
函数内部可以声明函数,返回函数

function fun1(a) {
    function fun2(b) {
        return a + b;
    }
    return fun2;
}
let a = fun1(1);
let b = a(2);     // 1 + 2 == 3
fun1(1)(2);       // 3

056 立即执行函数

函数定义完,立即执行

// 无参数例子
(function() {
    alert("6");
})()

// 有参数例子
(function(a, b) {
    console.log(a + b);
})(1, 2);

057 方法

函数作为对象属性,就称为对象的方法,调用函数就称为调用方法(method);函数与方法只是名称的区别

let obj = {};
obj.name = "123";
obj.age = 18;
obj.getName = function() {
    console.log(obj.name);
}

obj.getName();

枚举对象中的属性:for-in 语句,每次将一个属性名赋值给变量

for (let n in obj) {
    console.log(n);       // 输出属性名
    console.log(obj[n]);  // 输出属性值
}

058 全局作用域

JS 作用域有两种:全局作用域,函数作用域(局部作用域)

全局作用域

  • 直接编写在 script 标签的 JS 代码都在全局作用域
  • 全局作用域在页面打开时创建,关闭时销毁
  • 全局作用域中有一个全局对象 window,代表浏览器窗口可以直接使用
  • 全局作用域中创建的变量都会作为 window 对象的属性,函数都会作为 window 对象的方法
  • 变量与函数声明
    • 使用 var 声明的变量会在所有代码之前声明,但只有执行到这一行才赋值
    • 使用函数声明形式函数会在所有代码之前创建,写在任何位置都是一样的
    • 使用函数表达式的函数不会被提前创建
  • 全局作用域的变量都是全局变量

059 函数作用域(局部作用域)

函数作用域

  • 调用函数时创建函数作用域,执行完毕后作用域销毁
  • 每调用一次函数会创建一个新的函数作用域,不同的函数作用域相互独立
  • 函数作用域可以调用全局变量,全局中不能访问函数作用域的变量
  • 在函数作用域操作变量时,会先在作用域中找,如果未找到会向上一级作用域中寻找;如果仍未找到会报错 ReferenceError
  • 函数作用域的变量
    • 使用 var 声明的变量会在函数代码执行前声明;
    • 不使用 var 则会变成全局变量
    • 形参相当于函数作用域变量

使用 let 声明的变量都是局部变量

060 debug

如何 debug(以 Chrome 为例)
按 F12 打开开发者模式,切换到 Sources 页面
切换到 Page 找到页面源代码,在行数左侧点击以设置断点
在 Scope 中可以观察到全部变量,Watch 可以添加监控

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容