JS -关于对象相关介绍

在JS中,除去基本的数据类型,还有包含对象这种复合数据类型,他可以储存多个键值对,并且每个键都是唯一的,并且在对象中可以包含各种数据类型的值,包括其他对象,数组,函数等。对象是JavaScript中比较重要的一种数据结构,这篇博客我们将全部围绕JavaScript对象进行,用它来表示复杂的数据和结构化信息。

  • 对象是由{}包围,键值对之间通过逗号分隔,键值之间用冒号分隔。例如:
let person = {
  name: "John",
  age: 30,
  isStudent: false,
  hobbies: ["reading", "swimming"],
  address: {
    city: "New York",
    country: "USA"
  },
  greet: function() {
    console.log("Hello!");
  }
};

属性名和属性值

在JavaScript对象中,属性名(key)是用来唯一标识属性的字符串,而属性值(value)可以是任何数据类型,包括基本数据类型(如字符串、数字、布尔值、null、undefined)和复杂数据类型(如对象、数组、函数)。

属性名是对象中的键,用于访问和操作对象的属性。属性名是字符串类型,可以包含字母、数字、下划线和其他字符,但必须遵循标识符的命名规则。属性名是区分大小写的。

属性值是与属性相关联的数据,可以是任何JavaScript数据类型。属性值可以是基本数据类型,也可以是复杂数据类型。例如,一个属性的值可以是字符串、数字、布尔值,甚至是另一个对象或函数。

 /*
     *向对象中添加属性
     *属性名:
     * 对象的属性名不强制要求遵守标识符的规范
     * 什么乱七八糟的名字都可以使用
     * 但我们还是尽量按照标识符的规范去做
     * 如果要使用特殊的属性名,不能采用.的方式来操作
     * 例子 obj["123"]="hello";
     *  dpcument.write(obj["123"]);
     * JS对象的属性值可以使任意的数据类型
     * 
     */
    var obj=new Object();
    obj["123"]="hello";
    obj.text1="hello";
    document.write(obj["123"]+"<br>");
    document.write(obj.text1+"<br>");

    obj["456"]=789;
    obj["nihao"]="你好";
    var n="nihao";
    var m="456";
    document.write(obj[m]+obj[n]);
    console.log(obj);
    
    var area=new Object();
    area=obj;
    console.log(area);//可以依靠obj之间的赋值来进行obj的套娃

    /*
     *in运算符
     *通过该运算符可以检查一个对象中是否含有指定的属性
     * 如果有则返回true,没有则返回false
     * 语法:
     * "属性名" in 对象
     */
    //检查obj中是否含有test,text1属性名
    console.log("test" in obj);//obj中没有test属性名,所以输出false
    console.log("text1" in obj);//obj中有text1属性名,所以输出true
    console.log("text1" in area);//因为area继承了obj中所有的属性名,所以在area中检查是否存在text1,也会输出true

对象中基本数据类型和引用数据类型的比较

基本数据类型(Primitive Data Types):

  • 包括字符串(String)、数字(Number)、布尔值(Boolean)、空(Null)、未定义(Undefined)、Symbol(ES6新增)。
  • 基本数据类型的值直接存储在变量访问的位置,因此在比较时是按值比较的。
  • 当将一个基本数据类型的值赋给另一个变量时,会创建一个新的值的副本,而不是引用原始值。

引用数据类型(Reference Data Types):

  • 包括对象(Object)、数组(Array)、函数(Function)等。
  • 引用数据类型的值存储在内存中的堆内存中,变量中存储的是指向实际对象的引用。
  • 当将一个引用数据类型赋给另一个变量时,实际上是将引用复制给了新变量,因此两个变量指向同一个对象,修改其中一个变量会影响另一个变量。

在比较基本数据类型时,比较的是它们的值是否相等;而在比较引用数据类型时,比较的是它们在内存中的引用是否指向同一个对象。这是因为基本数据类型是按值访问的,而引用数据类型是按引用访问的。

    /*
     *基本数据类型
     *String Number Boolean Null Undefined
     * 引用数据类型
     * Object
     */
    //基本数据类型
    var a=123;
    var b=456;
    console.log("a="+a);
    console.log("b="+b);

    //引用数据类型
    var role1=new Object();
    role1.姓名="孙悟空";
    role1.职位="齐天大圣、斗战胜佛";
    role1.武器="如意金箍棒";

    var role2=new Object();
    role2.姓名="猪八戒";
    role2.职位="天蓬元帅、净坛使者菩萨";
    role2.武器="九齿钉耙";

    var role3=new Object();
    role3.姓名="沙悟净";
    role3.职位="卷帘大将、金身罗汉菩萨";
    role3.武器="降妖宝杖";

    var obj1=new Object();
    obj1.孙悟空=role1;
    obj1.猪八戒=role2;
    obj1.沙悟净=role3;
    
    role1.姓名="唐僧";//rol1.姓名由"孙悟空"变为了"唐僧",那么obj1引用的值也会随之变化
    console.log(obj1);//如果引用变量发生了改动,那么其余的引用的变量也会随之改动而不是不变
    //当一个值设置为null时,另一个引用该值的变量不会发生变化,会断开连接

在这里插入图片描述

    /*
     *基本数据类型同赋值比较
     */
    var a=10;
    var b=10;
    console.log(a == b);//控制台输出true
    
    //当比较两个基本数据类型的值时,就是比较他们的值
    //当比较两个引用数据类型时,它是比较的对象的内存地址
    //如果两个对象的值一样,但是地址不一样,它也会返回faLse
    var obj1=new Object();
    var obj2=new Object();
    obj1.name="沙和尚";
    obj2.name="沙和尚";
    console.log(obj1 == obj2);//虽然内部的name值一模一样,但是他们的内存地址不一样
    console.log(obj1.name == obj2.name);//这里相比就是比值了

对象的字面量

JavaScript对象的字面量是一种直接创建对象的方式,使用大括号 {} 来表示对象,其中包含零个或多个键值对。对象字面量是一种简洁、方便的方式来定义和初始化对象,而不需要使用构造函数。
本博客开头的那个JS示例就是:

let person = {
  name: "Alice",
  age: 25,
  isStudent: true,
  hobbies: ["reading", "painting"],
  address: {
    city: "London",
    country: "UK"
  }
};

person 对象使用对象字面量的方式创建,包含了几个属性:name、age、isStudent、hobbies 和 address。每个属性都是一个键值对,用冒号分隔键和值,用逗号分隔不同的键值对。

对象字面量是一种常见且方便的方式来创建对象,并且可以在需要时动态地添加或修改属性。

函数

JS中的函数function也是一个对象,函数中可以封装一些功能代码,在我们需要使用的时候执行这些功能代码,一般我们在函数中保存一些代码,在需要的时候调用,当我们使用typeof检查一个函数对象的时候,会返回一个function。

    //创建一个函数对象
    //可以将要封装的代码以字符串的形式传递给构造函数
    var fun = new Function("console.log('Hello,这是我的第一个函数');");
    console.log(fun);
    
    //封装到函数中的代码不会立即执行
    //函数中的代码会在函数调用的时候执行
    //调用函数 语法:函数对象()
    fun();
    
    //函数对象有普通对象的功能
    fun.world="你好";
    console.log(fun.world);

    //使用函数声明来创建一个函数
    //语法:
    //function 函数名([形参1,形参2,形参3,形参4])
    //{
    //}
    function fun2()
    {
        console.log("这是我的第二个函数~~~");
        document.write("这是我的第二个函数~~~<br>");
        alert("这是我的第二个函数~~~");
    }
    console.log(fun2);//这种情况不属于调用函数
    fun2();//这样属于直接调用函数
    
    //使用函数表达式来创建一个函数
    //var 函数名 = function([形参1,形参2,形参3……])
    //{
    //}
    var fun3 =function()
    {
        document.write("我是匿名函数中封装的代码");
    }
    fun3();

函数的call()和apply()方法

call() 方法:

  • call() 方法允许你调用一个函数,并指定函数内 this 的值,以及传入一个参数列表。
  • 语法:function.call(thisArg, arg1, arg2, …)
  • 第一个参数 thisArg 是函数内部的 this 指向的对象,可以是任何对象。
  • 后续的参数是传递给函数的参数列表。
function greet(name) {
  console.log(`Hello, ${name}! My name is ${this.name}.`);
}

let person = { name: "Alice" };
greet.call(person, "Bob");

apply() 方法:

  • apply() 方法与 call() 类似,但是接受一个参数数组作为参数。
  • 语法:function.apply(thisArg, [argsArray])
  • 第一个参数 thisArg 是函数内部的 this 指向的对象。
  • 第二个参数 argsArray 是一个数组,包含传递给函数的参数。
function greet(name) {
  console.log(`Hello, ${name}! My name is ${this.name}.`);
}

let person = { name: "Alice" };
greet.apply(person, ["Bob"]);

这两个方法允许你在调用函数时显式指定函数内部的 this 指向的对象,并且可以传递参数列表或参数数组给函数。这在某些情况下非常有用,特别是在需要动态改变函数执行上下文时。

    /*
     *call()和apply()
     *这两个方法都是函数对象的方法,需要通过函数对象来调用
     *党对函数调用call()和apply()都会调用函数执行
     *在调用call()和apply()可以将一个对象指定为第一个参数
     *此时这个对象将会成为函数执行时的this
     *call()方法可以将实参在对象之后依次传递
     *但是apply()方法需要将实参封装到一个数组中统一传递
     *this的情况
     *1.以函数形式调用时,this永远都是window
     *2.以方法的形式调用时,this是调用方法的对象
     *3.以构造函数的形式调用时,this是指定的那个对象
     *4.使用call和apply调用时,this是指定的那个对象
     */
    function fun(a,b)
    {
        console.log(a);
        console.log(b);
        console.log(this.name);
    }
    var obj={name:"obj1"};
    var arr=[2,3]
    fun.call(obj,2,3);
    fun.apply(obj,arr);
    console.log(obj);
    console.log(arr);
    
    //fun.call();
    //fun.apply();
    //fun();
    //上面三行代码效果一样
    
    
    //var obj2={name:"obj2"};
    //fun.call(obj);
    //此时输出的是objcet objcet 
    //如果不设定第一参数是obj,而是直接调用fun(),那么输出的则是object window

arguments

arguments 是一个类数组对象,它包含了函数被调用时传入的所有参数。即使函数定义时没有明确指定参数,也可以通过 arguments 对象访问到所有传入的参数。arguments 对象可以在函数内部使用,类似于一个数组,可以通过索引访问参数值。

function sum() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}

console.log(sum(1, 2, 3)); // 输出 6

sum 函数没有明确指定参数,但是通过 arguments 对象可以访问到所有传入的参数,并计算它们的总和。arguments 对象可以用来处理不定数量的参数,或者在不知道函数会接收多少参数的情况下进行处理。

需要注意的是,arguments 对象是一个类数组对象,不是一个真正的数组,因此它没有数组的方法,如 push()、pop() 等。如果需要将 arguments 对象转换为真正的数组,可以使用类似 Array.from(arguments) 或者 Array.prototype.slice.call(arguments) 的方法。

    /*
     *在调用函数时,浏览器每次都会传递进两个隐含的参数
     *1.函数的上下文对象this
     *2.封装实参的对象arguments
     *-arguments是一个类数组对象
     *类数组,但不是数组,所以判断是否是数组类型的时候会显示false
     *在调用函数时,我们所传递的实参都会在arguments中保存
     *arguments.length可以用来获取实参的长度
     *我们即使不定义形参,也可以通过arguments来使用实参
     *只不过比较麻烦
     *arguments[0]表示第一个实参 []中的数字就代表数组的索引
     *他里边有一个属性叫做callee
     *这个属性对应一个函数对象,就是当前正在指向的函数的对象
     */
    function fun()
    {
        console.log(arguments);
        //检查是否是数组可以有两个办法
        console.log(arguments instanceof Array);//此时控制台输出false
        console.log(Array.isArray(arguments));//次数控制台也是输出false
        //检查是否属于对象
        console.log(arguments instanceof Object);//此时控制台输出true
        //检查arguments的长度
        console.log(arguments.length);
    }
    fun();
    fun("hello");//此时长度输出为1
    fun("hellon","rock");//此时长度输出为2

    function fun1()
    {
        console.log(arguments[0]);
        console.log(arguments[2]);
    }
    fun1("a","b","c");

    function fun2(a,b)
    {
        //console.log(arguments);
        //检查是否是数组可以有两个办法
        //console.log(arguments instanceof Array);//此时控制台输出false
        //console.log(Array.isArray(arguments));//次数控制台也是输出false
        //检查是否属于对象
        //console.log(arguments instanceof Object);//此时控制台输出true
        //检查arguments的长度
        //console.log(arguments.length);
        //console.log(arguments.callee);//次方法会在控制台显示出当前函数的所有代码
        console.log(arguments.callee == fun2);
        //callee代表当前函数,所以控制台显示true
    }
    fun2();

Date对象

JS中使用Date对象来表示一个时间,Date 对象表示的是从1970年1月1日00:00:00 UTC(世界协调时间)开始经过的毫秒数。Date 对象可以用来获取当前日期和时间,以及进行日期和时间的计算、比较和格式化。

  • 创建 Date 对象:使用 new Date() 构造函数来创建一个 Date 对象。如果不传入任何参数,将会得到当前的日期和时间。
    例如:
 let currentDate = new Date();
  • 获取日期和时间:Date 对象有多个方法用于获取日期和时间的各个部分,如 getFullYear()、getMonth()、getDate()、getHours()、getMinutes() 等。
    例如:
let year = currentDate.getFullYear();
let month = currentDate.getMonth();
let day = currentDate.getDate();
  • 日期和时间的计算:Date 对象可以进行日期和时间的计算,如加减天数、小时数等。
    例如:
currentDate.setDate(currentDate.getDate() + 1); // 将日期加一天
  • 格式化日期和时间:可以使用 toLocaleString()、toLocaleDateString()、toLocaleTimeString() 等方法将日期和时间格式化为本地时间字符串。
    例如:
let formattedDate = currentDate.toLocaleString();
    //创建一个Date对象
    //如果直接使用构造函数创建一个Date对象,则会封装为当前代码执行的时间
    var d=new Date();
    console.log(d);

    //创建一个指定的时间对象
    //需要在构造函数中传递一个表示时间的字符串作为参数
    //日期格式 月份/日/年 时:分:秒
    var d2=new Date("12/03/2016 11:10:30");
    console.log(d2);
    
    //getDate()
    //获取当前日期对象是几日
    var date=d2.getDate();
    console.log(date);
    
    //getDay()获取当前日期对象是星期几
    //他会显示0-6的值,其中0代表星期日
    var day=d2.getDay();
    console.log(day);
    
    //getMonth()会获取当前日期对象的月份
    //它会显示0-11的值,其中每个数字+1后的值代表着月份
    //比如0代表一月份,1代表二月份
    var month=d2.getMonth();
    console.log(month);
    
    //getFullYeart()获取当前日期对象的年份
    //以四位数字返回获取到的年份的值
    var year=d2.getFullYear();
    console.log(year);

    //其余的类似方法
    //getHours()获取日期对象的小时0-23
    //getMinutes()获取日期对象的分钟0-59
    //getSeconds()获取日期对象的秒数0-59
    //getMilliseconds()获取日起对象的毫秒0~999

    //getTime()
    //获取当前日期对象的时间戳
    //时间戳,指的是从格林威治标准时间的1970年1月1日,0时0分0秒
    //到当前日期所花费的毫秒数(1秒=1000毫秒)
    //给系统设置的时间按系统情况断定时区,我们输入的时间按北京时间算,所以跟格林威治标准时间不是同一个时间
    var ds=d2.getTime();
    var ds2=d.getTime();
    console.log(ds);
    console.log(ds2);

    //Date()获取当前日期
    var dt=Date();
    console.log(dt);

    //Date,now()获取当前的时间戳
    //这个时间戳指运行的那个时间相对于格林威治标准时间的时间戳
    d=Date.now();
    console.log(d);

    //利用时间戳来测试代码的执行的性能
    var start=Date.now();
    for(i=0;i<100;i++)
    {
        console.log("测试代码运行性能");
    }
    var end=Date.now();
    console.log("执行时间:"+(end - start)+"毫秒");

Math对象

Math 对象是一个内置的数学对象,提供了许多数学常量和方法,用于进行数学计算。Math 对象中的方法和属性都是静态的,可以直接通过 Math 对象访问,而不需要创建实例。

常用属性:

  • Math.PI:表示圆周率 π 的近似值(3.14159…)。
  • Math.E:表示自然对数的底 e 的近似值(2.71828…)。

常用方法:

  • Math.abs(x):返回参数 x 的绝对值。
  • Math.round(x):将参数 x 四舍五入为最接近的整数。
  • Math.floor(x):返回小于或等于参数 x 的最大整数。
  • Math.ceil(x):返回大于或等于参数 x 的最小整数。
  • Math.max(x, y, z, ...):返回参数中的最大值。
  • Math.min(x, y, z, ...):返回参数中的最小值。
  • Math.random():返回一个大于等于 0 且小于 1 的随机数。
  • Math.sqrt(x):返回参数 x 的平方根。
  • Math.pow(x, y):返回 x 的 y 次幂。
  • Math.sin(x)、Math.cos(x)、Math.tan(x):返回参数 x 的正弦、余弦、正切值等三角函数值。
    /*
     *Math和其他的对象不同,他不是一个构造函数
     *它属于一个工具类不用创建对象,它里面封装了数学运算相关的属性和方法
     */    
    /*Math的对象属性
     *E 返回算术常量e,即自然对数的底数(约2.718)
     *LN2 返回2的自然对数(约等于0.693)
     *LN10 返回10的自然对数(约等于2.302)
     *LOG2E 返回以2为底的e的对象(约等于1.414)
     *LOG10E 返回以10为底的e的对数(约等于0.434)
     *PI 返回圆周率(约等于3.1415926)
     *SQRT1_2 返回2的平方根的倒数(约等于0.707)
     *SQRT2 返回2的平方根(约等于1.414)
     */
    //例如输出圆周率
    console.log(Math.PI);

    //Math的方法
    //例如abs()可以用来计算一个数的绝对值
    console.log(Math.abs(3-8888));

    //Math.ceil()可以对一个数进行向上取整,小数位只有有值就自动进1
    //Math.floor()可以对一个数进行向下取整,小数部分会被舍去
    //Math.round()可以对一个数进行四舍五入
    //Math.random()可以生成一个0-1之间的随机数
    console.log(Math.ceil(1.0055));
    console.log(Math.floor(1.55));
    console.log(Math.round(2.49));
    console.log(Math.random());

    for(i=0;i<100;i++)
    {
        console.log(Math.random());
    }

    //max()可以获取多个数中的最大值
    //min()可以获取多个数中的最小值
    var max=Math.max(14,156,214,153,45,789,324,45,38,453,453,4,34,534,3541,5,4,561,3,153,4,531,35,153,4);
    var min=Math.min(45,1,53,135,4,5314,53,453,435,135,15,41,53,153,135,1,53,13,11,5,453,1,354,53,135,453,1,534,45);
    console.log(max);
    console.log(min);

    //pow(x,y)可以获取x的y次幂
    var pow=Math.pow(5,3);
    console.log(pow);

    //sqrt(x)可以获取x的平方根
    var sqrt=Math.sqrt(81);
    console.log(sqrt);

包装类

在JavaScript中,有三个包装类(Wrapper Classes):StringNumberBoolean。这些包装类允许将基本数据类型(字符串、数字、布尔值)包装成对象,以便可以调用对象的方法和访问对象的属性。

String 包装类:String 包装类允许将基本数据类型的字符串包装成一个字符串对象。
例如:

let str = "Hello";
let strObj = new String(str);

Number 包装类:Number 包装类允许将基本数据类型的数字包装成一个数字对象。
例如:

let num = 10;
let numObj = new Number(num);

Boolean 包装类:Boolean 包装类允许将基本数据类型的布尔值包装成一个布尔对象。
例如:

let bool = true;
let boolObj = new Boolean(bool);

尽管可以使用包装类将基本数据类型包装成对象,但在实际开发中,通常直接使用基本数据类型,而不是使用包装类。这是因为 JavaScript 引擎会自动将基本数据类型转换为对象,以便可以调用对象的方法和访问对象的属性。因此,可以直接在基本数据类型上使用方法和属性,而无需显式地创建包装对象。

例如,可以直接使用字符串的方法和属性,而不需要创建 String 对象:

let str = "Hello";
console.log(str.length); // 输出 5
 /*
     *基本数据类型
     *String Number Boolean Null Undefined 
     * 引用数据类型
     * Object
     * 在JS中为我们提供了三个包装类,通过这三个包装类可以将基本数据类型小的数据转换为对象
     * String()可以将基本数据类型字符串转换为String对象
     * Number()可以将基本数据类型的数字转换为Number
     * Boolean()可以将基本数据类型的布尔值转换为Boolean对象
     * 在日常情况中,不会使用基本数据类型的对象
     * 如果使用基本数据类型的对象,在做一些比较时可能会带来一些不可预期的一些结果
     */
    var num1 =new Number(3);//此时num1是object
    var num2 =3;//此时num2是Number类型
    var str1 =new String("hello");//此时str1是object
    var str2 ="hello";//此时str2是String类型
    var bool1=new Boolean(true);//此时bool1是object
    var bool2=true;//此时bool2是Boolean类型
    console.log(typeof num1);
    console.log(typeof num2);
    console.log(typeof str1);
    console.log(typeof str2);
    console.log(typeof bool1);
    console.log(typeof bool2);

    //因为设置了num1
    num1.text1="Hello,World!";
    console.log(num1.text1);//控制台显示Hello,Wordld!
    console.log(num1);//控制台显示num1这个项目中的所有属性

    //方法和属性只能添加给对象,不能添加给基本数据类型
    //当我们对一些基本数据类型的值去调用属性和方法时
    //浏览器会临时使用包装类将其转换为对象,然后在调用对象的属性和方法
    //调用完以后,再将其转换为基本数据类型。所以再转换类型后,给a添加一个属性,也不会在控制台显示,这个属性已经被销毁了
    var a=123;
    a=a.toString();
    console.log(a);
    console.log(typeof a);

关于字符串的相关方法

  • charAt(index):返回指定索引位置的字符。
  • charCodeAt(index):返回指定索引位置的字符的 Unicode 值。
  • length:返回字符串的长度(字符的个数)。
  • substring(startIndex, endIndex):返回从 startIndex 到 endIndex(不包括)之间的子字符串。
  • slice(startIndex, endIndex):返回从 startIndex 到 endIndex(不包括)之间的子字符串。与 substring() 类似,但支持负数索引。
  • indexOf(searchValue, startIndex):返回指定字符串在原字符串中首次出现的索引位置。如果未找到,返回 -1。
  • lastIndexOf(searchValue, startIndex):返回指定字符串在原字符串中最后一次出现的索引位置。如果未找到,返回 -1。
  • toUpperCase():将字符串转换为大写。
  • toLowerCase():将字符串转换为小写。
    /*
     *创建一个字符串
     */
    var str="HelloWorlld"
    /*
     *在底层字符串是以字符数组的形式保存的
     *["H","e","l","l","o"…………]
     */
    
     //length可以用来获取字符串的长度
    console.log(str.length);//输出字符长度12
    console.log(str[0]);//输出第一个字符H

    //返回字符串中指定位置的字符
    //charAT(),返回指定索引位置的值
    //该方法不会对原字符串产生影响
    var result =str.charAt(2);
    var result2=str[2];
    console.log(result);//会返回指定的索引位置的值
    console.log(result2);//效果跟上面的charAT(2)一样

    //charCodeAt()
    //返回字符串中指定的索引位置的值的Unicode编码值
    var result3=str.charCodeAt(2);
    console.log(result3);//输出了l在Unicode编码中的值,也就是108 

    //String.fromCharCode()
    //返回字符编码中指定的值的字符编码
    var result4=String.fromCharCode(78);//注意()中的值的进制
    console.log(result4);

    //concat()
    //可以用来连接两个或者多个字符串
    //作用和+一样
    //不会对原字符串产生影响
    var result5,str1,str2;
    str1="Hello";
    str2="World";
    result5=str1.concat(str2);
    console.log(result5);

    //indexOf()
    //检索字符串,该方法可以检查一个字符串中是否含有指定内容
    //如果字符串中含有该内容,则会返回其第一次出现的索引
    //如果没有找到指定的内容,则是返回-1
    //()中可以传递两个参数,第一个为索引值,第二个为索引位置的值
    var str3="hello atguigu";
    var result6=str3.indexOf("g");
    var result7=str3.indexOf("g",9);
    console.log(result7);
    console.log(result6);

    //lastIndexOf()
    //相比于indexOf()不同的是一个是从前往后找,一个是从后往前找,但是找到的结果的位置索引还是按从前往后算
    //第二个参数也是起始位置索引,从输入的起始索引开始从后往前找
    //方向改变,索引位置还是不变

    //slice()
    //可以从字符串中截取指定的内容
    //对原字符串没有任何影响
    //同样是可以输入两个参数,一个是起始位置索引,一个是结束位置索引,但是截取的字符串包括起始位置不包括结束位置
    var str4="abcdefghijk";
    var result8=str4.slice(0,5);
    var result9=str4.slice(0);
    var result10=str4.slice(0,-1);//负数表示倒数,所以-1表示倒数第一,不输出结束位置索引
    console.log(result8);//输出abcde(不包括f)
    console.log(result9);//只有起始位置索引,没有结束位置,默认输出后面的所有字符串
    console.log(result10);//输出abcdefghij

    //substring()
    //可以用来截取一个字符串,可以slice()类似
    //两个参数的使用跟slice()类似,都是起始位置索引和结束位置索引 
    //这个方法不能接受负值作为参数,如果传递了一个负值,折磨人使用0
    //他还自动调整参数的位置,如果第二个参数小于第一个,则自动交换
    var result11=str4.substring(1,2);
    console.log(result11);

    //substr()
    //用来截取字符串
    //同样是可以传递两个参数,第一个参数是起始位置索引值,第二个参数是索引的数量(索引的长度)
    //不影响原字符串
    var result12=str4.substr(1,2);
    console.log(result12);

    //split()
    //可以将一个字符串拆分为一个数组
    var str5="abc,bcd,efg,hij";
    var result13=str5.split(",");
    //如果传递一个空串作为参数,则会将每个字符都拆分为数组中的每一个元素
    console.log(result13);//这样的话,就会以,为标识符把字符串分开
    //最后就会输出一个数组
    console.log(result13[1]);//控制台输出数组的第二个元素,即bcd
    console.log(typeof result13);//此时输出的object而不是string
    console.log(Array.isArray(result13));//控制台输出的是true,确认result13是数组
    console.log(result13.length);//控制台输出的长度是4,也就是四个元素

    //toUpperCase()
    //将一个字符串转换为大写并且返回
    var str6="abcdefg一二";
    var result14=str6.toUpperCase();
    console.log(result14);//小写字母变成了大写字母

    //tuLowerCase()
    //将一个字符串转换为小写并且返回
    var str7="ABCDEFG";
    var result15=str7.toLowerCase();
    console.log(result15);//大写字母变成了小写字母

函数参数

/*
     *定义一个用来求两个数和的函数
     *可以在函数的()中来指定一个或多个形参(形式参数)
     *多个形参之间使用,隔开,声明形参就相当于在函数内部生命了对应的变量
     *但是并不赋值
     */
     function sum(num1,num2)
     {
         document.write(num1+num2+"<br>");
     }
     sum(123,456);
     //在调用函数时,可以再()中指定实参(实际参数)
     //实参将会赋值给函数中华对应的形参
     //调用函数时,解析器不会检查实参的类型
     sum(123,"hello");//输出123hello

     //调用函数时,解析器不会检查实参的数量
     //多余实参不会被使用
     sum(123,456,"hell","hello");

     //特殊情况,实参缺失
     sum(1);//此时b的值是undefined,所以相加为NaN

返回值

/*
     *创建一个函数,用来计算三个数的和
     *可以使用return来设置函数的返回值
     * 语法:
     * return 值
     * return后的值将会作为函数的执行结果返回
     * 可以定义一个变量来读取该结果
     * return后面的语句都不会执行
     * 没有明确返回值或者输出值的话,获取的值默认undefined
     */
    function sum(a,b,c)
    {
        var d=a+b+c;
        return d;
    }
    var result=sum(7,8,9);
    console.log(result);
    /*
     *函数常规流程
     */
    function fun1()
    {
        alert("我要开始装逼了");
        for(i=1;i<=5;i++)
        {
            document.write(i+"<br>");
            //break可以退出当前循环结构
            //continue可以用于跳过档次循环
            //return直接返回当值,并且不执行后面的代码,即结束整个函数
        }
        alert("我装逼完了");
    }

        //fun()
        //return返回值可以使任意的数据类型
        //也可以是一个对象,也可以是一个函数
        function fun2()
        {
            var obj={name:"沙和尚"};
            return obj;
        }
        var a=fun2();
        console.log(a.name);

立即执行函数

在 JavaScript 中,立即执行函数(Immediately Invoked Function Expression,IIFE)是一种在定义后立即执行的函数表达式。它可以用于创建一个独立的作用域,避免变量污染和全局命名冲突。

(function() {
  // 函数体
})();
let result = (function(name) {
  return "Hello, " + name + "!";
})("Alice");

console.log(result); // 输出 "Hello, Alice!"

在这个例子中,立即执行函数接受一个参数 name,并返回一个拼接了问候语的字符串。通过在函数定义后立即调用,并传递参数 “Alice”,可以立即执行函数并将结果赋值给变量 result。

函数的作用域

函数内部定义的变量和函数在函数内部可访问的作用域。这意味着在函数内部定义的变量和函数只能在函数内部被访问,而在函数外部是不可见的。
变量的作用域:

  • 在函数内部使用 var 关键字声明的变量具有函数作用域,也称为局部变量。
  • 在函数外部声明的变量具有全局作用域,也称为全局变量。
function myFunction() {
  var localVar = "I am a local variable";
  console.log(localVar); // 在函数内部可以访问局部变量
}

myFunction();
console.log(localVar); // 报错,无法在函数外部访问局部变量

函数的作用域链:

  • 函数作用域链是指函数内部可以访问外部函数的变量,以及全局作用域中的变量。
  • 当函数在内部访问一个变量时,它首先在自己的作用域中查找,如果找不到,则沿着作用域链向上查找,直到找到变量或到达全局作用域。
var globalVar = "I am a global variable";

function outerFunction() {
  var outerVar = "I am an outer variable";

  function innerFunction() {
    var innerVar = "I am an inner variable";
    console.log(innerVar); // 在内部函数中访问内部变量
    console.log(outerVar); // 在内部函数中访问外部变量
    console.log(globalVar); // 在内部函数中访问全局变量
  }

  innerFunction();
}

outerFunction();

枚举对象中的属性

  • for…in 循环: 使用 for…in 循环可以遍历枚举对象的所有可枚举属性(包括继承的属性)。
    const Colors = {
      RED: "red",
      GREEN: "green",
      BLUE: "blue"
    };
    
    for (let key in Colors) {
      console.log(key); // 输出 RED, GREEN, BLUE
    }
    
  • Object.keys() 方法: 使用 Object.keys() 方法可以获取枚举对象的所有可枚举属性的键组成的数组。
    const Colors = {
      RED: "red",
      GREEN: "green",
      BLUE: "blue"
    };
    
    let keys = Object.keys(Colors);
    console.log(keys); // 输出 ["RED", "GREEN", "BLUE"]
    
  • Object.values() 方法: 使用 Object.values() 方法可以获取枚举对象的所有可枚举属性的值组成的数组。
       const Colors = {
         RED: "red",
         GREEN: "green",
         BLUE: "blue"
       };
    
       let values = Object.values(Colors);
       console.log(values); // 输出 ["red", "green", "blue"]
      ```
    
  • Object.entries() 方法: 使用 Object.entries() 方法可以获取枚举对象的所有可枚举属性的键值对组成的数组。
        const Colors = {
          RED: "red",
          GREEN: "green",
          BLUE: "blue"
        };
    
        let entries = Object.entries(Colors);
        console.log(entries); // 输出 [["RED", "red"], ["GREEN", "green"], ["BLUE", "blue"]]
    

这些方法可以帮助我们获取枚举对象的属性,以便进行遍历、查找、过滤等操作。需要注意的是,for…in 循环会遍历对象的原型链上的属性,而 Object.keys()、Object.values() 和 Object.entries() 方法只会获取对象自身的可枚举属性。

JS的作用域Scope

全局作用域(Global Scope):

  • 全局作用域是在整个代码中都可访问的作用域。
  • 在全局作用域中定义的变量和函数可以在代码的任何地方被访问。
    例如,在全局作用域中定义的变量:
let globalVariable = "I am in global scope";

函数作用域(Function Scope):

  • 函数作用域是在函数内部定义的变量和函数可访问的作用域。
  • 在函数作用域中定义的变量和函数只能在函数内部被访问。
    例如,在函数作用域中定义的变量:
function myFunction() {
let localVariable = "I am in function scope";
}

块级作用域(Block Scope):

  • 块级作用域是在代码块(如 if、for、while 语句块)内部定义的变量可访问的作用域。
  • 在块级作用域中定义的变量只能在块级作用域内部被访问。
    例如,在块级作用域中定义的变量:
 if (true) {
 let blockVariable = "I am in block scope";
  }

this

this 是一个特殊的关键字,用于引用当前执行上下文中的对象。它的值取决于函数的调用方式和上下文。

函数调用方式:

  • this 的值取决于函数的调用方式。
  • 当函数作为对象的方法调用时,this 指向调用该方法的对象。
  • 当函数作为普通函数调用时,this 指向全局对象(在浏览器中是 window 对象)。
const obj = {
  name: "Alice",
  greet: function() {
    console.log("Hello, " + this.name + "!");
  }
};

obj.greet(); // 输出 "Hello, Alice!"

function sayHello() {
  console.log("Hello, " + this.name + "!");
}

sayHello(); // 输出 "Hello, undefined!"(在浏览器中输出 "Hello, [全局对象的名称]!")

构造函数中的 this:

  • 当函数作为构造函数使用时,this 指向新创建的对象。
  • 在构造函数中,可以使用 this 来引用新创建的对象,并将属性和方法添加到该对象上。
function Person(name) {
  this.name = name;
  this.greet = function() {
    console.log("Hello, " + this.name + "!");
  };
}

const person = new Person("Alice");
person.greet(); // 输出 "Hello, Alice!"

显式绑定 this:

  • 可以使用 call()、apply() 或 bind() 方法来显式地绑定函数的 this 值。
  • 这些方法允许在调用函数时指定 this 的值,并传递参数给函数。
const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };

function greet() {
  console.log("Hello, " + this.name + "!");
}

greet.call(obj1); // 输出 "Hello, Alice!"
greet.apply(obj2); // 输出 "Hello, Bob!"

const greetBob = greet.bind(obj2);
greetBob(); // 输出 "Hello, Bob!"

   /*
     *浏览器在调用函数每次都会向函数内部传递进一个隐含的参数
     *这个隐含的参数就是this,this指向的是一个对象
     *这个对象我们称为函数执行的上下文对象
     *根据函数的调用方式的不同,this会指向不同的对象
     *1.以函数的形式调用时,this永远都是window
     *2.以方法的形式调用时,this就是调用方法的那个对象
     *如果是函数调用,那么就可以引用全局变量,如果var name="孙悟空"
     *那么this.name =window.name="孙悟空"
     */
    function fun()
    {
        console.log(this);
    }
    fun();
    var obj=
    {
        name:"孙悟空",
        sayName:fun
    };
    obj.sayName();
    fun();
    //创建一个name变量
    var name="全局";//此时name属于全局变量,即window.name

    //创建一个fun()函数
    function fun()
    {
        console.log(this.name);
    }

    //创建两个对象
    var obj =
    {
        name:"孙悟空",
        sayName:fun
    };

    var obj2 =
    {
        name:"沙和尚",
        sayName:fun
    };
    //
    fun();
    obj.sayName();
    obj2.sayName();

    //我们希望调用obj.sayName()时可以输出obj的名字

函数声明和变量声明

函数声明(Function Declaration)和变量声明(Variable Declaration)都会被提升(Hoisting)到当前作用域的顶部。这意味着在代码执行之前,函数声明和变量声明的定义就已经存在于内存中,可以在声明之前使用。

函数声明的提升意味着可以在函数声明之前调用函数,例如:

greet(); // 可以在函数声明之前调用

function greet() {
  console.log("Hello!");
}

变量声明的提升意味着可以在变量声明之前使用变量,但是变量的值会被提升为 undefined,例如:

console.log(name); // 可以在变量声明之前访问,但值为 undefined

var name = "Alice";

需要注意的是,虽然函数声明和变量声明都会被提升,但是函数表达式(Function Expression)和变量赋值不会被提升。例如:

greet(); // 报错,函数表达式没有被提升

var greet = function() {
  console.log("Hello!");
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/558984.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[AI]-(第0期):认知深度学习

深度学习是一种人工智能&#xff08;AI&#xff09;方法&#xff0c;用于教计算机以受人脑启发的方式处理数据。 深度学习模型可以识别图片、文本、声音和其他数据中的复杂模式&#xff0c;从而生成准确的见解和预测。 您可以使用深度学习方法自动执行通常需要人工智能完成的…

linux 基础命令docker及防火墙iptables详解

应用场景&#xff1a; web应用自动打包和发布 自动化测试&#xff0c;持续集成、发布 在服务环境中部署后台应用 搭建paaS平台 安装应用 apt install docker.io#kali中 配置docker源&#xff0c;文件位置/etc/docker/daemon.json { "registry-mirrors": [ "h…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之一 简单人脸识别

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之一 简单人脸识别 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之一 简单人脸识别 一、简单介绍 二、简单人脸识别实现原理 三、简单人脸识别案例实现简单步…

ContextMenuStrip内容菜单源对象赋值学习笔记(含源码)

一、前言 MetroTileItem属于第三方控件,无法定义ContextMenuStrip属性 想实现某子项点击菜单时,与源控件(按钮metroTileItem)的某值对应,用于动态控制按钮的状态或方法 1.1 效果 二、实现方法 2.1 方法1 (代码,说明见注释) private void metroTileItem_MouseDown(o…

基于Springboot的小区物业管理系统

基于SpringbootVue的小区物业管理系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 用户管理 员工管理 业主信息管理 费用信息管理 楼房信息管理 保修信息…

攻防世界---reverse_re3

1.下载附件&#xff0c;先查壳&#xff1a;无壳 2.在IDA中分析&#xff0c;shiftfnf5&#xff0c;看到一串长得很像flag的flag 3.根据提示我们需要找到输入&#xff0c;再进行md5转换才能得到flag flag{md5(your input)} 4.双击这个句话&#xff0c;点进去想查看信息&#xff0…

MongoDB学习【一】MongoDB简介和部署

MongoDB简介 MongoDB是一种开源的、面向文档的、分布式的NoSQL数据库系统&#xff0c;由C语言编写而成。它的设计目标是为了适应现代Web应用和大数据处理场景的需求&#xff0c;提供高可用性、横向扩展能力和灵活的数据模型。 主要特点&#xff1a; 文档模型&#xff1a; Mon…

西宁市初中生地会考报名照片尺寸要求及手机自拍方法

西宁市初中生地会考即将到来&#xff0c;对于参加考试的同学们来说&#xff0c;准备一张符合规格的报名照片是整个报名流程中不可或缺的一环。一张规范的证件照不仅展示了学生的精神面貌&#xff0c;同时也是顺利报名的重要条件之一。本文将详细介绍西宁市初中生地会考报名所需…

SSDReporter for Mac:全面检测SSD健康,预防数据丢失,让您的Mac运行更稳定

SSDReporter for Mac是一款专为Mac用户设计的固态硬盘&#xff08;SSD&#xff09;健康状况检测工具&#xff0c;旨在帮助用户全面了解并监控其Mac设备中SSD的工作状态&#xff0c;从而确保数据的完整性和设备的稳定性。 这款软件具有多种强大的功能。首先&#xff0c;它能够定…

【分治】Leetcode 库存管理 III

题目讲解 LCR 159. 库存管理 III 本题的含义就是让求出最小的k个数 算法讲解 class Solution { public:void my_qsort(vector<int>& nums, int l, int r){if(l > r) return ;int i l, left l-1, right r1;int key nums[rand() % (r - l 1) l];//完成分三…

深度学习基础之《TensorFlow框架(12)—图片数据》

一、图像基本知识 1、如何转换图片文件 回忆&#xff1a;之前我们在特征抽取中讲过如何将文本处理成数据 思考&#xff1a;如何将图片文件转换成机器学习算法能够处理的数据&#xff1f; 我们经常接触到的图片有两种&#xff0c;一种是黑白图片&#xff08;灰度图&#xff09;…

C++ - STL详解—vector类

一. vector的概念 向量&#xff08;Vector&#xff09;是一个封装了动态大小数组的顺序容器&#xff08;Sequence Container&#xff09;。跟任意其它类型容器一样&#xff0c;它能够存放各种类型的对象。可以简单的认为&#xff0c;向量是一个能够存放任意类型的动态数组。 …

阿里云ECS服务器安装docker

首先查看阿里云ECS的服务器的版本 cat /etc/redhat-release如果是Alibaba Cloud Linux release 3,请执行以下命令 添加docker-ce的dnf源。 sudo dnf config-manager --add-repohttps://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装Alibaba Cloud Linux 3专…

深度学习每周学习总结P5(运动鞋识别)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 –来自百度网盘超级会员V5的分享 目录 0. 总结1. 数据导入及处理部分2. 加载数据集3.模型构建部分3.1 模型构建3.2 公式推导 4. 设置超参…

小型燃气站3D可视化:打造安全高效的燃气新时代

随着科技的不断进步&#xff0c;越来越多的行业开始融入3D可视化技术&#xff0c;燃气行业也不例外。 小型燃气站作为城市燃气供应的重要节点&#xff0c;其安全性和运行效率至关重要。传统的燃气站管理方式往往依赖于人工巡检和纸质记录&#xff0c;这种方式不仅效率低下&…

开源大数据集群部署(二十一)Spark on yarn 部署

作者&#xff1a;櫰木 1 spark on yarn安装&#xff08;每个节点&#xff09; cd /root/bigdata/ tar -xzvf spark-3.3.1-bin-hadoop3.tgz -C /opt/ ln -s /opt/spark-3.3.1-bin-hadoop3 /opt/spark chown -R spark:spark /opt/spark-3.3.1-bin-hadoop32 配置环境变量及修改配…

BFS解决八数码问题-java

本文主要通过BFS广度优先搜索来解决八数码问题。 文章目录 前言 一、八数码 二、算法思路 1.思路模拟 2.实现思路 三、代码 1.代码如下&#xff1a; 2.读入数据 3.代码运行结果 总结 前言 本文主要通过BFS广度优先搜索来解决八数码问题。 提示&#xff1a;以下是本篇文章正文内…

有没有手机上使用的库存软件

库存软件是一种仓库的信息管理系统&#xff0c;它主要针对出库与入库这些数据进行管理&#xff0c;传统的库存管理都是在电脑上安装一个专门的数据库管理系统进行管理&#xff0c;这也是一种比较成熟的管理方式&#xff0c;那么有没有手机上使用的库存软件。 手机上使用的库存软…

开发工具——postman使用教程详解

一、概念 1、Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件&#xff0c;Postman分为Postman native app和Postman Chrome app两个版本。目前Chrome app已停止维护&#xff0c;官方不推荐使用该版本。 2、官网下载地址&#xff1a;http://www.getpostman.com…

离线数仓数据导出-hive数据同步到mysql

离线数仓数据导出-hive数据同步到mysql MySQL建库建表数据导出 为方便报表应用使用数据&#xff0c;需将ads各指标的统计结果导出到MySQL数据库中。 datax支持hive同步MySQL&#xff1a;仅仅支持hive存储的hdfs文件导出。所以reader选hdfs-reader&#xff0c;writer选mysql-wri…