js高级内存、作用域、变量、引用类型

目录

一、变量

1、基本类型和引用类型

(1)、基本类型指的是保存在栈内存中简单数据段,即这种值完全保存在内存中的一个位置。

(2)、引用类型则是指保存在堆内存中的对象,意思是变量中(栈)保存的实际上是一个指针,而这个指针指向内存中的堆。

2、动态属性:

 3、复制变量值

(1)、基本数据复制变量值,会在栈中创建一个新值,然后把该值复制到新变量分配的位置上。num1和num2是完全独立的,这两个变量将来的任何操作都不会相互影响。

 (2)、引用数据复制变量值会在栈中复制一份放到新变量的分配空间中,不同的是,这个值是一个指针,而这个指针指向存储在堆中的一个对象,两个变量实际上引用一个对象。因此,改变其中一个变量,就会影响到另外一个变量。

4、传递参数

(1)、传递的参数是基本数据类型

 (2)、传递的参数是引用数据类型

 5、检测类型

(1)、typeof只能检测字符串、数值、布尔值、undefined,如果检测Array,Date,null返回值都是object。

 (2)、instanceof用于检测引用数据类型。

二、作用域

三、引用类型

1、Object类型

(1)、第一种是new操作符后面跟Object构造函数

(2)、另一种方式是使用对象字面量表示法 

 (3)、使用点表示法访问对象

(4)、使用方括号访问对象属性

 2、Array类型

(1)、第一种是使用new关键字后面加上Array构造函数创建,也可以省略new关键字。

(2)、第二种是使用数组字面量[]来创建数组。

(3)、数组的增删查改方法:

(4)、转换方法:

 (5)、栈方法:

 (6)、队列方法:

(7)、重排序方法

(8)、操作方法:

(9)、splice方法是数组中特别强大的方法之一

 3、Date类型

 4、RegExp类型

search方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。

replace 方法用于在字符串中用一些字符串替换另一些字符串,或替换一个与正则表达式匹配的子串。

test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。

exec() 方法用于检索字符串中的正则表达式的匹配。

1、Boolean类型:

2、Number类型:

3、string类型:

(1)、字符方法:

(2)、字符串操作方法:

3、indexOf()和lastIndexOf()方法,这两个方法不同于,一个是向前寻找药要查找的字符串,一个是向后寻找要查找的字符串,查找到了就返回位置值,如果没有查找到就返回-1,这个方法可以接受第二个参数,就是忽略已经查找到的字符串,向后或者向前继续查找。

4、大小写转换方法:toLowerCase()小写转换,toUpperCase()大写转换。

5、字符串的模式匹配方法:

6、Math对象:


一、变量

1、基本类型和引用类型

(1)、基本类型指的是保存在栈内存中简单数据段,即这种值完全保存在内存中的一个位置。

(2)、引用类型则是指保存在堆内存中的对象,意思是变量中(栈)保存的实际上是一个指针,而这个指针指向内存中的堆。

基本数据类型:undefined,null,boolean,number,string,symbol

引用数据类型:object,object包含了(function,Date,Array)

2、动态属性:

对于引用数据类型,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。

/* 引用数据类型创建动态值 */
        let obj = new Object()
        obj.name = 'zs'
        console.log(obj, obj.name);

结果:

对于基本数据类型,如果为其添加属性和方法,虽然不会报错,但是在访问属性的时候显示未定义,所以我们只能动态的为引用数据类型创建动态属性。

/* 基本数据类型创建动态值 */
        let string = 'name'
        string.age = 20
        console.log(string, string.age);

结果:

 3、复制变量值

(1)、基本数据复制变量值,会在栈中创建一个新值,然后把该值复制到新变量分配的位置上。num1和num2是完全独立的,这两个变量将来的任何操作都不会相互影响。

let num1 = 5
        let num2 = new Number()
        num2 = num1
        console.log('我是num1=', num1, '我是num2=', num2);
        num2 = 10
        console.log('我是num1=', num1, '我是num2=', num2);

 结果:

 (2)、引用数据复制变量值会在栈中复制一份放到新变量的分配空间中,不同的是,这个值是一个指针,而这个指针指向存储在堆中的一个对象,两个变量实际上引用一个对象。因此,改变其中一个变量,就会影响到另外一个变量。

let obj1 = {
            name: 'zs',
            age: 20,
            play() {
                console.log('我爱打游戏!');
            }
        }
        let obj2 = {}
        obj2 = obj1
        console.log('我是obj1', obj1, '我是obj2', obj2);
        obj2.name = 'ls'
        console.log('我是obj1', obj1, '我是obj2', obj2);

结果:

 封装深拷贝函数:

let obj1 = {
            name: 'zs',
            age: 20,
            play() {
                console.log('我爱打游戏!');
            }
        }
        let obj2 = {}
        obj2 = deepClone(obj1)
        console.log('修改obj2.name属性前', '我是obj1', obj1, '我是obj2', obj2);
        obj2.name = 'ls'
        console.log('修改obj2.name属性后', '我是obj1', obj1, '我是obj2', obj2);

        function deepClone(obj) {
            if (typeof obj !== 'object') return obj

            let result

            if (result instanceof Array) {
                result = []
            } else {
                result = {}
            }

            for (key in obj) {
                result[key] = deepClone(obj[key])
            }

            return result
        }

结果:

4、传递参数

所有函数的参数都是按值传递,引用类型的参数也是按值传递。

(1)、传递的参数是基本数据类型

function setNum(num) {
            num += 10
            return num
        }
        let num = 20
        let result = setNum(num)
        console.log('我是全局变量的num', num, '我是函数的返回值', result);

结果:

 (2)、传递的参数是引用数据类型

function setObj(obj) {
            obj.name = 'zs'
        }
        let obj1 = {}
        setObj(obj1)
        console.log('我是未更改前的obj1', obj1.name, '我是未更改前的函数', setObj);
        obj1.name = 'ls'
        console.log('我是更改后的obj1', obj1.name, '我是更改后的函数', setObj);

结果:

 5、检测类型

(1)、typeof只能检测字符串、数值、布尔值、undefined,如果检测Array,Date,null返回值都是object。

 (2)、instanceof用于检测引用数据类型。

let arr = []
        let obj = {}
        console.log(arr instanceof Array, arr instanceof Object);
        console.log(obj instanceof Array, obj instanceof Object);

结果:

注意:当被检测的对象是数组的时候,instanceof Object和instanceof Array都为true

当被检测的对象是对象的时候,instanceof Array和instanceof Object分别为false和true 

二、作用域

作用域:一段程序代码中所用到的变量并不总是有效的,而限定这个变量的可用性的代码范围就是这个变量的作用域。

作用域链:当你要访问一个变量时,首先会在当前作用域下查找,如果当前作用域下没有查找到,则返回上一级作用域进行查找,直到找到全局作用域,这个查找过程形成的链条叫做作用域链。

内部环境可以通过作用域链访问所有的外部环境,但外部环境不可以访问内部环境的变量和函数。

let color1 = 'red'
        function colorHandler1() {
            color2 = 'green'
            console.log(color1, color2);
            try {
                console.log(color3);
            } catch (error) {
                console.log(error);
            }
            function colorHandler2() {
                color3 = 'blue'
                console.log(color1, color2, color3);
            }
            colorHandler2()
        }
        colorHandler1()

结果:

三、引用类型

1、Object类型

创建Object实例的方式有两种:

(1)、第一种是new操作符后面跟Object构造函数

let person = new Object()
        person.name = 'zs',
            person.age = 20
        person.play = function () {
            console.log('我要打游戏!');
        }
        console.log(person);

结果:

(2)、另一种方式是使用对象字面量表示法 

let person = {
            name: 'zs',
            age: 20,
            watch() {
                console.log('我要看电视!');
            }
        }
        console.log(person);

结果:

访问对象的两种方法:

 (3)、使用点表示法访问对象

let person = {
            name: 'zs',
            age: 20,
            watch() {
                console.log('我要看电视!');
            }
        }
        console.log(person);
        console.log(person.name, person.age);
        person.watch()

结果:

(4)、使用方括号访问对象属性

let person = {
            name: 'zs',
            age: 20,
            watch() {
                console.log('我要看电视!');
            }
        }
        console.log(person);
        console.log(person['name']);
        let propertyAge = 'age'
        console.log(person[propertyAge]);

结果:

使用方括号访问对象的属性,可以通过变量来访问属性。

 2、Array类型

与其他语言不同的是,javascript数组的每一项可以保存任何数据类型,第一项可以是字符串,第二项可以使number,第三项可以是对象。

创建数组的方式有两种:

(1)、第一种是使用new关键字后面加上Array构造函数创建,也可以省略new关键字。

let arr=new Array()与let arr=Array()结果相同

(2)、第二种是使用数组字面量[]来创建数组。

let arr=[]与Array构造函数创建效果相同

传入不同值得结果:

/* 1、给构造函数传递数量,
        此时如果我们访问数组的每一项,
        结果会返回undefined */
        let arr1 = Array(20)
        console.log(arr1);
        for (let i = 0; i < arr1.length; i++) {
            console.log(arr1[i]);
        }
        console.log('~~~~~~~~~~');
        /* 2、给构造函数传递应该包含的项 */
        let arr2 = Array('red', 'green', 'blue')
        console.log(arr2);
        console.log('~~~~~~~~~~');
        /* 3、创建一个空数组 */
        let arr3 = []
        console.log(arr3);
        console.log('~~~~~~~~~~');
        /* 4、创建一个包含1、2、'ls'、obj对象的数组 */
        let arr4 = [1, 2, 'ls', { name: 'zs', age: 20, play() { console.log('我要打游戏!'); } }]
        arr4.forEach(item => console.log(item))
        console.log('~~~~~~~~~~');
        /* 5、通过浏览器bug创建数组,一般建议不要这么做 */
        let arr5 = [, , , , ,]
        console.log(arr5.length);

结果:

(3)、数组的增删查改方法:

/* (1)、在数组中添加项: */
        let arr = ['red', 'green', 'blue']
        console.log(arr);
        console.log('~~~~~~~~~~');
        /* (2)、在数组中删除项: */
        /* 此时数组的长度为3, */
        console.log(arr[2]);
        arr.length = 2
        console.log(arr[2]);
        console.log('~~~~~~~~~~');
        /* (3)、在数组中查找项: */
        console.log(arr[0]);
        console.log('~~~~~~~~~~');
        /* (4)、在数组中改变项: */
        arr[1] = 'pink'
        console.log(arr);

结果:

(4)、转换方法:

数组的转换方法有三种:其中toString()和toLocaleString()方法转换数组的效果一致,返回结果都是字符串,而valueOf()返回的结果是一个数组对象。

let arr1 = ['red', 'green', 'blue']
        let arr2 = ['red', 'green', 'blue']
        let arr3 = ['red', 'green', 'blue']
        console.log(typeof arr1.toString(), arr1.toString());
        console.log('~~~~~~~~~~');
        console.log(typeof arr2.toLocaleString(), arr2.toLocaleString());
        console.log('~~~~~~~~~~');
        console.log(typeof arr3.valueOf(), arr3.valueOf());

结果:

 (5)、栈方法:

栈是一种后入先出的数据结构(last-in-first-out)简称LIFO,栈的压入和弹出都在栈的顶部,也就是数组的末尾进行。

/* 1、压栈也称为推栈 */
        let arr = ['red', 'green', 'blue']
        console.log(arr);
        /* 可以压入任意项 */
        arr.push('pink', 'purple')
        console.log(arr);
        console.log('~~~~~~~~~~');
        /* 2、弹出也称为出栈,一次只可以弹出一项 */
        arr.pop()
        console.log(arr);
        arr.pop()
        console.log(arr);

结果:

 (6)、队列方法:

队列是一种先进先出的数据结构(frist-in-frist-out)简称FIFO,队列在末尾添加项,在前端移除项。

/* 我们可以使用push和shift模拟队列 */
        let arr1 = ['red', 'green', 'blue']
        /* 1、在队列的末尾加入项 */
        arr1.push('pink', 'purple')
        console.log(arr1);
        /* 2、在队列的前端移除项 */
        arr1.shift()
        console.log(arr1);
        console.log('~~~~~~~~~~');
        /* 我们可以使用unshift和pop来模拟反队列 */
        let arr2 = ['red', 'green', 'blue']
        /* 1、在队列的前端推入项 */
        arr2.unshift('pink', 'purple')
        console.log(arr2);
        /* 2、在队列的后端弹出项 */
        arr2.pop()
        console.log(arr2);

结果:

(7)、重排序方法

sort方法:默认情况下,sort排序是升序,先调用每个数组项的toString()转型方法,获得字符串,会根据比较字符串的结果改变原来的顺序。

虽然5>10,但是比较字符串时,会先比较字符串的第一个字符,比较'5'和'1','5'位于'1'的后面,所以5排在了10的后面。

let arr = [0, 1, 5, 10, 15]
        let result = arr.sort()
        console.log(result);

结果:

这样的排序不是最佳的,sort()方法可以传递一个函数

let arr = [0, 5, 1, 15, 10]
        let result1 = arr.sort(asc)
        console.log('调用升序方法', result1);
        console.log('~~~~~~~~~~');
        let result2 = arr.sort(desc)
        console.log('调用降序方法', result2);
        /* 升序方法 */
        function asc(num1, num2) {
            if (num1 < num2) {
                return -1
            } else if (num1 > num2) {
                return 1
            } else {
                return 0
            }
        }
        /* 降序方法 */
        function desc(num1, num2) {
            if (num1 < num2) {
                return 1
            } else if (num1 > num2) {
                return -1
            } else {
                return 0
            }
        }

结果:

reverse方法,用于反转数组:

let arr = [1, 10, 5, 0, 15]
        let result = arr.reverse()
        console.log(arr);

 结果:

(8)、操作方法:

concat方法方法可以基于当前数组中的所有项创建一个新数组,将接受到的参数追加到新数组的末尾。

let arr = ['red', 'green', 'blue']
        let result = arr.concat('pink', ['purple', 'white'])
        console.log(result);

结果:

slice方法可以基于当前数组创建一个新数组,slice方法接受两个参数,起始位置参数和结束位置参数,如果只传递一个参数,返回从该数组起始的位置到数组末尾的所有项;如果传递两个参数,返回从数组起始的位置到数组结束的位置(不包含结束位置的项)。

let arr = [1, 2, 3, 4, 5]
        let result1 = arr.slice(1)
        console.log('传递一个参数', result1);
        let result2 = arr.slice(2, 4)
        console.log('传递两个参数', result2);

结果:

 

(9)、splice方法是数组中特别强大的方法之一

删除:需要向splice传入两个参数,第一个参数是要删除项的起始位置,第二个参数是要删除几项。

let arr1 = [1, 2, 3, 4, 5]
        arr1.splice(1, 2)
        console.log(arr1);

结果:

 插入:需要向splice传入三个参数,第一个参数是插入项的起始位置(插入到该位置前),第二个参数必需是0,第三个参数是插入的项。

let arr2 = [1, 2, 3, 4, 5]
        arr2.splice(2, 0, 10, 15)
        console.log(arr2);

结果:

替换:需要向splice传入三个参数,第一个参数是替换项的起始位置,第二个参数是替换几项,第三个参数是替换的项。

let arr2 = [1, 2, 3, 4, 5]
        arr2.splice(2, 2, 100, 120, 150)
        console.log(arr2);

结果:

 3、Date类型

封装时间函数

/* 封装时间函数 */
        function getNowTime() {
            let Time = new Date()
            let year = Time.getFullYear()
            year = year > 10 ? year : '0' + year
            let month = Time.getMonth() + 1
            month = month > 10 ? month : '0' + month
            let date = Time.getDate()
            date = date > 10 ? date : '0' + date
            let hours = Time.getHours()
            hours = hours > 10 ? hours : '0' + hours
            let minutes = Time.getMinutes()
            minutes = minutes > 10 ? minutes : '0' + minutes
            let seconds = Time.getSeconds()
            seconds = seconds > 10 ? seconds : '0' + seconds
            let week = Time.getDay()
            let string = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
            week = string[week]
            return `${year}-${month}-${date} ${hours}:${minutes}:${seconds} ${week}`
        }

        console.log(getNowTime());

结果:

 4、RegExp类型

语法:/正则表达式主体/修饰符(可选)

修饰符:g表示全局模式,模式被用于所有字符串,而非在发现第一个匹配项时立即停止;

i表示不区分大小写模式,在确定匹配项时忽略模式与字符串的大小写;

m表示多行模式,即在到达一行文本末尾时还会继续查找下一行中是否存在于模式匹配的项。

使用字符串方法

在 JavaScript 中,正则表达式通常用于两个字符串方法 : search() 和 replace()。

search方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。

replace 方法用于在字符串中用一些字符串替换另一些字符串,或替换一个与正则表达式匹配的子串。

/* search方法使用正则表达式 */
        let string = 'hello world'
        let result1 = string.search(/w/g)
        console.log(result1);
        /* search方法使用字符串 */
        let result2 = string.search('w')
        console.log(result2);

结果:

/* replace方法使用正则表达式 */
        let str = 'hello world'
        let result1 = str.replace(/world/g, 'xjl')
        console.log(result1);
        /* replace方法使用字符串 */
        let result2 = str.replace('world', 'xjl')
        console.log(result2);

 结果:

test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。

let str = 'hello world'
        let patt1 = /e/g
        let patt2 = /x/g
        let result1 = patt1.test(str)
        let result2 = patt2.test(str)
        console.log(result1, result2);

 结果:

exec() 方法用于检索字符串中的正则表达式的匹配。

该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。

避坑:使用exec方法时,使用全局匹配会出现存在的值但是返回值为null

let str = 'hello world'
        let patt1 = /h/
        let patt2 = /x/
        let result3 = patt1.exec(str)
        let result4 = patt2.exec(str)
        console.log(result3, result4);

结果:

 Function类型:

每个函数都是Function的实例,而且都与其他引用类型一样具有属性和方法,由于函数是对象,因此函数名实际上是一个指向Function的指针。

创建函数:

/* 1、使用函数声明语法定义 */
        function sum1(num1, num2) {
            return num1 + num2
        }
        /* 2、使用函数表达式定义函数 */
        let sum2 = function (num1, num2) {
            return num1 + num2
        }
        /* 3、使用Function构造函数定义函数 */
        let sum3 = new Function('num1', 'num2', 'return num1+num2')
        /* 4、使用箭头函数定义函数 */
        let sum4 = (num1, num2) => { return num1 + num2 }

        console.log(sum1(1, 2));
        console.log(sum2(3, 4));
        console.log(sum3(5, 6));
        console.log(sum4(7, 8));

结果:

function函数没有重载,因为JavaScript中函数名是一个指针。

重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的​​​​​​​形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个函数完成不同的功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。不能只有函数返回值类型不同。 

函数声明与函数表达式的区别:

解析器会率先读取函数声明,并将其添加到执行环境中,并使其在执行任何代码之前都可用;至于函数表达式,则必须等到解析器执行到它那行代码才会执行。

console.log(sum1(1, 2));
        function sum1(num1, num2) {
            return num1 + num2
        }

结果:

console.log(sum2(3, 4));
        let sum2 = function (num1, num2) {
            return num1 + num2
        }

 结果:

作为值得函数:

不仅可以像传递传递参数一样把一个函数传递给另外一个函数,而且可以将一个函数作为另一个函数的结果返回。

function handler(somenfunction, functionParam) {
            return somenfunction(functionParam)
        }
        function add10(num) {
            return num + 10
        }
        let result = handler(add10, 10)
        console.log(result);

结果:

函数内部属性:arguments和this

arguments是一个类数组对象,它包含着传入函数的所有参数,虽然它主要的作用是用于保存函数参数,但是,这个函数还有一个叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。arguments.callee的作用是为了消除紧密耦合的现象,就算你原来声明的函数被你置空,你任然可以继续使用以前声明的函数。

/* 定义阶乘函数 */
        function factorial(num) {
            if (num <= 1) {
                return 1
            } else {
                return num * factorial(num - 1)
            }
        }
        console.log(factorial(10));
        let trueFactorial = factorial
        factorial = function () {
            return 0
        }
        console.log(trueFactorial(10));

 结果:

使用arguments.callee则不会出现这种结果:

/* 定义阶乘函数 */
        function factorial(num) {
            if (num <= 1) {
                return 1
            } else {
                return num * arguments.callee(num - 1)
            }
        }
        console.log(factorial(10));
        let trueFactorial = factorial
        factorial = function () {
            return 0
        }
        console.log(trueFactorial(10));

结果:

this是函数在执行是所处的作用域,在不同的作用域this指向不同的作用域:

window.color = 'red'
        let o = { color: 'green' }
        function sayColor() {
            console.log(this.color);
        }
        /* 在全局中调用sayColor,this指向全局作用域 */
        sayColor()
        /* 在局部调用sayColor,this指向局部o作用域 */
        o.sayColor = sayColor
        o.sayColor()

结果:

函数属性和方法

JavaScript中函数也是对象,因此函数也有属性和方法,每个函数窦包含两个属性:length和prototype。其中,length属性表示函数希望接受的命名参数个数。

function handler1() {
            console.log('hello world');
        }
        function handler2(name) {
            console.log(name);
        }
        function handler3(name, age) {
            console.log(name, age);
        }
        function handler4(arguments) {
            console.log(arguments);
        }
        console.log(handler1.length);
        console.log(handler2.length);
        console.log(handler3.length);
        console.log(handler4.length);

结果:

对于JavaScript引用类型而言,prototype是保存实例方法的真正所在。

每个函数窦包含两个非继承而来的方法:apply和call,这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。

apply方法接受两个参数:第一个参数是在其中运行函数的作用域,另一个是参数组,其中第二个参数可以是Array的实例,也可以是arguments对象。

function sum(num1, num2) {
            return num1 + num2
        }
        function applysum1(num1, num2) {
            return sum.apply(this, arguments)
        }
        function applysum2(num1, num2) {
            return sum.apply(this, [num1, num2])
        }
        console.log(applysum1(10, 10));
        console.log(applysum2(10, 20));

结果:

function callsum1(sum1, sum2) {
            return sum.call(this, sum1, sum2)
        }
        console.log(callsum1(10, 30));

结果:

call与apply方法不同于第二个参数,call在传递第二个参数时,必须是逐个列举出来。

call与this最强大的地方不在于传递参数,而在于改变this的指向,扩充作用域。

function sayColor() {
            console.log(this.color);
        }
        window.color = 'red'
        let o = { color: 'green' }
        sayColor()
        sayColor.call(o)

结果:

基本包装类型:boolean、number、string,每当读取一个基本类型值得时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。

let s1='hello world!'

let s2=s1.substring(2)

这个例子中,s1包含了一个字符串,字符串属于基本类型,不属于引用类型,从逻辑上讲,不应该有方法或者属性,而JavaScript为了能让我们对字符串进行一些操作,就在后台完成了一系列操作。

(1)、创建String类型的一个实例;

let s1=new String('hello world')

(2)、在实例上调用指定的方法;

let s2=s1.subString(2)

(3)、销毁这个实例;

s1=null

引用类型与基本包装类型的主要区别就是对象的生命周期,使用new创建的引用类型实例,在执行流离开当前作用域之前都一直保存在内存中,而包装类型的对象,则只存在于一行代码中的执行瞬间,然后立即销毁。这就意味着我们不能为基本类型添加属性和方法。

1、Boolean类型:

最常见的问题:

let boolean1 = new Boolean(false)
        let result1 = boolean1 && true
        let boolean2 = false
        let result2 = boolean2 && true
        console.log(result1, result2);

 结果:

虽然在实例化时,你为构造函数传入了false,但是,布尔表达式在所有对象中都会被转换为true,所以我建议永远不要使用Boolean对象。

2、Number类型:

.toString()方法传递一个表示基数的参数,传入2表示转换为2进制,8表示8进制等等。

.toFixed()方法传递一个基数的参数,传入2表示保留两位小数,这个方法普遍用于货币。

3、string类型:

(1)、字符方法:

charAt()返回指定位置的字符:

let str = 'hello world!'

console.log(str.charAt(1));//e

charCodeAt()返回返回指定字符的字符编码: 

let str = 'hello world!'

console.log(str.charCodeAt(2));//105

(2)、字符串操作方法:

concat()方法用于拼接字符串,可以接受多个需要拼接的参数,可以拼接任意多个字符:

let str = 'hello'
        let result1 = str.concat('world', 'javascript')
        /* concat方法等价于+操作符 */
        let result2 = `${str} world javascript`
        console.log(result1);
        console.log(result2);

结果:

slice(),substr(),substring():这三个方法的第一个参数都一样,都是指定子字符串的开始位置,第二个参数不一样,slice()和substring()都是字符串的结束位置,而substr()是截取字符串的长度。

如果不给这三个方法传递第二个参数,它们都是从起始位置到字符串的结束位置。

let str = 'helloworld'
        let result1 = str.slice(1, 5)
        let result2 = str.substring(1, 5)
        let result3 = str.substr(1, 5)
        console.log(result1, result2, result3);

结果:

如果字符串中间出现空格,则 substr()方法会把空格也计算到截取长度,而slice(),substring()方法会忽略空格截取字符串。

3、indexOf()和lastIndexOf()方法,这两个方法不同于,一个是向前寻找药要查找的字符串,一个是向后寻找要查找的字符串,查找到了就返回位置值,如果没有查找到就返回-1,这个方法可以接受第二个参数,就是忽略已经查找到的字符串,向后或者向前继续查找。

let str = 'A true master always has the heart of an apprentice'
        console.log(str.indexOf('a'));
        console.log(str.lastIndexOf('a'));

结果:

优化indexOf函数:

let str = 'A true master always has the heart of an apprentice'
        console.log(findCharacter(str, 'a'));
        function findCharacter(string, character) {
            let position = []
            let pos = string.indexOf(character)
            while (pos > -1) {
                position.push(pos)
                pos = string.indexOf(character, pos + 1)
            }
            return position
        }

结果:

4、大小写转换方法:toLowerCase()小写转换,toUpperCase()大写转换。

let str = 'A true master always has the heart of an apprentice'
        let result1 = str.toUpperCase()
        console.log(result1);
        let result2 = result1.toLowerCase()
        console.log(result2);

结果:

5、字符串的模式匹配方法:

match()只接受一个参数,要么是正则表达式,要么是RegExp对象。

let str = 'cat,bat,sat,fat'
        let patt = /.at/g
        let matches = str.match(patt)
        console.log(matches);

结果:

 search()方法参数与match()方法参数相同。

let str = 'cat,bat,sat,fat'
        let patt = /.at/g
        let searches = str.search(patt)
        console.log(searches);

结果:

replace()方法接受的一个参数是字符串,也可以是RegExp对象,第二个参数是字符串,也可以是函数,如果第一个参数是字符串,那么只会替换掉一个子字符串。

let str = 'cat,bat,sat,fat'
        let result1 = str.replace('at', 'ont')
        console.log(result1);
        let result2 = str.replace(/at/g, 'ont')
        console.log(result2);

结果:

6、Math对象:

min取最小值,max取最大值,ceil向上舍入,floor向下舍入,round四舍五入,random随机数。

/* 封装自定义生成函数,len表示要生成几个随机数,
        flag=1表示四舍五入,flag=2表示向上取整,flag=3表示向下取整,
        range表示范围,10表示0~10,100表示0~100,以此类推 */

        function randomNum(flag, len, range) {
            let result = []
            for (let i = 0; i < len; i++) {
                if (flag == 1) {
                    let random = Math.round(Math.random() * range)
                    result.push(random)
                } else if (flag == 2) {
                    let random = Math.ceil(Math.random() * range)
                    result.push(random)
                } else if (flag == 3) {
                    let random = Math.floor(Math.random() * range + 1)
                    result.push(random)
                }

            }
            let max = Math.max(...result)
            let min = Math.min(...result)
            console.log('随机生成的随机数有', result);
            console.log('最小值为', min);
            console.log('最大值为', max);
        }
        randomNum(3, 10, 10)

结果:

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值