js基础

1.简介

JavaScript的数据类型共有7种:

基本数据类型六种:

数值(number)

字符串(string)

布尔值(boolean)

undefined

null

symbol

引用数据类型一种:

对象(object array function)

基本类型的值放在栈区的(栈区指内存里的栈内存)

引用类型的值同时保存在栈内存和堆内存的对象中,栈区内存保存变量标识符和指向堆内存中该对象的指针

2.运算符

JavaScript确定一个值到底是什么类型有下列几种方式

(1)typeof操作符可以返回一个值的数据类型,可以不加括号,主要有7种:number string   boolean undefined(数据未被声明或者未初始化)  object(null或者对象) symbol和函数类型 function

(2)Instanceof运算符可以区分数组和对象  []  instanceof  Array; //true

(3)区分对象,数组和null  Object.prototype.toString.call(null) //[object Null]

(4)Array.isArray(arr) //判断数组

(5)constructor也能判断类型,undefined和null没有这个属性

  '[]'.constructor==Array

3.数据类型

undefined==null //true   Number(null) //0  5+null //5  Number(undefined) //NaN  5+undefined //NaN

Null与undefined的区别是:null是一个表示“空”的对象,转为数值时为0;undefined是一个表示“此处无定义”的原始值,转为数值时为NaN.

undefined null false 0 NaN “” ‘’ 被转为false,其他值都视为true

空数组([])和空对象({})对应的布尔值都是true

整数和浮点数:1===1.0//true  0.1+0.2===0.3//false  0.3/0.1 //2.999999  (0.3-0.2)===(0.2-0.1) //false

0.1+0.2!=0.3的原因:

这是使用基于IEEE754数值的浮点计算的通病,浮点数值的最高精度是17位小数,进行算数运算时其精确度远远不如整数,存在舍入误差,其结果为0.30000000000000004

解决方式:Math.abs(0.1+0.2-0.3)<Number.EPSILON

数值的表示法:

十进制:没有前导0的数值

八进制:有前缀0o或00的数值,或者有前导0,且只用到0-7的八个阿拉伯数字的数值。

十六进制:有前缀0x或0X的数值。

二进制:有前缀0b或0B的数值。

几乎所有的场合正零和负零都会被当做正常的0,唯一有区别的场合是,+0和-0当做分母,返回的值是不相等的。除以正零得到+Infinity,除以负零得到-Infinity,这两者是不相等的。

NaN表示“非数字”,主要出现在将字符串解析成数字出错的场合

5-‘x’ //NaN  0/0 //NaN  typeof NaN //’number’

NaN不等于任何值,包括它本身,数组的indexOf方法内部使用的是严格相等运算符,所以[NaN].indexOf(NaN) //-1

NaN在布尔运算时被当做false。Boolean(NaN) //false

NaN与任何数(包括它自己)的运算,得到的都是NaN

Boolean([]); //true

Number([]); //0

Number({}); // NaN

Number(false); //0

任何对象转为布尔值,都为得到 true(切记!在 JS 中,只有 0,-0,NaN,"",null,undefined 这六个值转布尔值时,结果为 false)

4.与数值相关的全部方法

parseInt() 用于将字符串转为整数

parseFloat() 用于将一个字符串转为浮点数

isNaN方法可以用来判断一个值是否为NaN

判断NaN的方法:

function myisNaN(value){

           return typeof value===’number’ && isNaN(value);

}

function myisNaN(value){

           return value !== value;

}

isFinite方法返回一个布尔值,表示某个值是否为正常的数值。

isFinite(Infinity) //false

isFinite(-Infinity) //false

isFinite(NaN) //false

isFinite(undefined) //false

isFinite(null) //true

isFinite(-1) //true

js中不改变原来数组对象的方法

map concat slice filter,forEach,some,every                                       

js中改变原数组的方法:

pop push shift sort splice unshift

丢弃小数部分,保留整数部分parseInt(7/2)

向上取整,有小数就整数部分加1 Math.ceil(7/2)

四舍五入math.round(7/2)

向下取整Math.floor(7/2)

取几位小数:Math.toFixed()

5.字符串

字符串与数组的相似性仅此而已,实际上无法改变字符串之中的单个字符,字符串内部的单个字符无法改变和增删,这些操作会默默地失败。

length属性返回字符串的长度,该属性也是无法改变的

6.对象

对象是一组“键值对”的集合,是一种无序的复合数据集合

对象的引用:如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量,如果取消某个变量对于原对象的引用,不会影响到另一个变量。

属性的操作:

读取对象的属性有两种方法:一种是使用点运算符,另一种是使用方括号运算符

方括号运算符内部可以使用表达式,数值键名不能使用点运算符(因为会被当做小数点)。

查看一个对象本身的所有属性:可以使用Object.keys(obj)方法

属性的删除:delete命令delete obj.p //true

Delete命令只能删除对象本身的属性,无法删除继承的属性。

属性是否存在:in运算符用于检查对象是否包含某个属性,如果包含就返回true,否则就返回false。‘toString’ in obj //true

可以使用对象的hasOwnProperty方法判断一下,是否为对象自身的属性。obj.hasOwnProperty(‘toString’) //false

属性的遍历:for…in循环

for…in循环用来遍历一个对象的全部属性。

7.with语句

操作同一个对象的多个属性,提供一些书写的方便

var obj = {p1:1,p2:2,};

with(obj) { p1 =4; p2 =5;}

// 等同于

obj.p1 =4;

obj.p2 =5;

如果width区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量

var obj = {};

with(obj) { p1 =4; p2 =5;}

obj.p1// undefined

p1// 4

8.函数

三种声明函数的方式:

function命令:function(){}

函数表达式:var s=function(){}

Function构造函数:var add =new Function('x','y','return x + y');

函数的重复声明:如果同一个函数被多次声明,后面的声明就会覆盖前面的声明

函数名的提升:采用function声明函数时,整个函数会像变量声明一样,被提升到代码头部,也就是在调用之前已经声明了。

如果同时采用function命令和赋值语句声明同一个函数,采用赋值语句的定义。

函数的属性:

name属性  返回函数名字

length属性  返回函数定义时的参数个数

函数的toString()方法返回函数的源码

函数参数,如果是原始类型的值,传递方式是传值传递,在函数体内修改参数值,不会影响函数外部;如果是复合类型的值(数组、对象、其他函数),传递方式是传址传递,修改函数体内的参数值会影响函数外部。注意:如果函数体内修改的不是对象的属性而是替换了整个对象的值,不会影响原始值。

arguments对象的长度由传入的参数个数决定的,不是由定义时参数的个数决定的。arguments对象可以读取函数所有的对象,arguments的callee属性,返回他所对应的原函数,可以通过这个调用自身,但是严格模式下不能使用。

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

函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用。而函数表达式的值是在JS运行时确定,并且在表达式赋值完成后,该函数才能调用。

9.执行环境

定义了变量或函数有权访问的其他数据,决定了他们各自的行为,每个执行环境都有一个与之关联的变量对象。

10.作用域、作用域链

作用域:

(1)全局作用域

任何地方都能访问到的的对象有全局作用域,函数外部定义的变量、未定义直接赋值的变量、window对象的属性

(2)局部作用域

函数内部

(3)块级作用域

let const声明,在指定块作用域外部不能访问。

函数本身也有自己的作用域,它的作用域与变量一样,就是函数声明时所在的作用域,与函数运行时的作用域无关。

作用域链:

(1)当执行函数时,总是先从函数内部找寻局部变量

(2)如果内部找不到(函数的局部作用域没有),则会向创建函数的作用域(声明函数的作用域)寻找,依次向上,直到查到全局作用域,这个查找过程形成的链条就叫作用域链。

11.垃圾收集

JavaScript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存。

原理:找出不再使用的变量,释放其内存。

标记清除、

引用计数:存在循环引用问题,可以通过解除引用来解决。

12.数组

typeof运算符会返回数组的类型是object

Object.keys(arr)返回数组的所有键名

length属性返回数组的成员数量,该属性是一个动态的值,等于键名中的最大整数加上1

in运算符检测某个键名是否存在,适用于对象也适用于数组

for...in循环和数组的遍历 数组遍历一般使用for while forEach

两个逗号之间没有任何值,称该数组存在空位

使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。

数组的slice可以将“类似数组的对象arrayLike”转换成数组  Array.prototype.slice.call(arrayLike)

数组的迭代方法:

every(){ }对数组中的每一项运行给定函数,如果每一项都返回true,则返回true

filter(){}对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组

forEach(){}对数组中的每一项运行给定函数,没有返回值

map(){}对数组中的每一项运行给定函数,返回函数调用结果组成的数组

some(){}对数组中的每一项运行给定函数,如果有一项返回true,则返回true

reduce()从数组的第一位开始,遍历到最后一位

reduceRight()从数组的最后一位开始,向前遍历

13.基本包装类型

Boolean String Number

生存期:只存在一行的代码执行瞬间,然后立即被销毁

14.Number()

将任意类型的数据转换成数值,Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN。

parseInt ('42 cats')// 42

Number ('42 cats')// NaN

15.String()

将任意类型的数据转化成字符串,String方法转换规则,先调用toString,再调用valueOf,与Number方法调用顺序相反

charAt  charCodeAt  fromCharCode

16.Boolean()

将任意类型的值转换成布尔类型,除了以下五种boolean值为false,其他的都为true

undefined null 0(包含-0和+0) NaN  ''(空字符串)

所有对象的布尔值都为true

17.创建对象

工厂模式

创建对象解决了创建多个相似对象的问题,没有解决对象识别问题(怎样知道一个对象的类型)

function createperson(name,age,job){

    var o=new Object();

    o.name=name;

    o.age=age;

    o.job=job;

    o.sayname=function(){

        return this.name;

    }

    return o;

}

var person1=createperson('haha',5,'teacher');

构造函数模式

可以创建特定类型的对象,但是每定义一个实例都有方法,且方法不是同一个Function的实例

function Person(name,age,job){

    this.name=name;

    this.age=age;

    this.job=job;

    this.sayname=function(){

        return this.name;

    }

}

var person1=new Person('haha',5,'teacher');

原型模式

使用原型对象可以让所有实例共享它所包含的属性和方法。

1.对象都有属性__proto__,指向该对象的构造函数的原型对象。函数方法也是一种对象

2.方法除了有属性__proto__,还有属性prototype,prototype指向该方法的原型对象。

hasOwnProperty()判断一个属性存在于实例中还是原型对象中

取一个对象上所有可枚举的实例属性 Object.keys()

想要得到所有实例属性 Object.getOwnPropertyNames()

原型模式的问题:由其共享性导致的,尤其是包含引用类型值时。

组合使用原型模式和构造函数模式

function persionc(name,age){

    this.name=name;

    this.age=age;

}

persionc.prototype={

    constructor:persionc,

    sayname:function(){

        alert(this.name);

    }

}

寄生构造函数模式

除了用new新建实例外,跟工厂模式一模一样

适用于想创建一个具有额外方法的特殊数组,由于不能直接修改Array构造函数,就用这种模式

18.继承

方法一

实现继承,通过原型链来实现

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的constructor指针,而实例都包含一个指向构造函数原型对象的内部指针,让子类原型对象等于父类的实例,此时,子类原型对象将包含一个指向父类原型的指针。如果父类原型又是另一个类型的实例,如此层层递进,就构成实例与原型的链条,这就是所谓原型链的概念。

//实现继承

function supertype(){

    this.superval=true;

}

supertype.prototype.getsuper=function(){

    console.log(this.superval);

}

function subtype(){

    this.subval=false;

}

subtype.prototype=new supertype();

subtype.prototype.getsub=function(){

    console.log(this.subval);

}

var a=new subtype();

原型链的问题:(1)包含引用类型值的原型属性会被所有实例共享

(2)不能在不影响所有对象实例的情况下,向超类构造函数传递参数

方法二

借用构造函数技术

原理:在子类构造函数内部调用超类构造函数

function sup(name){

    this.name=name;

    this.color=['red','blue'];

}

function sub(){

    sup.call(this,'haha');

}

var a=new sub();

var b=new sub();

a.color.push('pink');

console.log(a.color);

console.log(b.color);

console.log(b.name);

问题:函数复用无从谈起

方法三

组合原型继承和构造函数

原理:通过原型对象实现对原型属性和原型方法的继承,通过构造函数实现实例属性的继承。

function sup1(name){

    this.name=name;

    this.colors=['red','blue'];

}

sup1.prototype.getname=function(){

    console.log(this.name);

}

function sub1(name,age){

    sup1.call(this,name);

    this.age=age;

}

sub1.prototype=new sup1();

sub1.prototype.constructor=sub1;

sub1.prototype.getage=function(){

    console.log(this.age);

}

var instance1=new sub1('a',4);

var instance2=new sub1('b',8);

instance1.colors.push('pink');

console.log(instance1.colors);

console.log(instance2.colors);

instance1.getname();

instance2.getname();

instance1.getage();

instance2.getage();

19.函数表达式

(1)定义函数的方式,递归

函数声明、函数表达式

arguments.callee是一个指向正在执行的函数的指针

function factorial(num){

    if(num<=1) return 1;

    else  return num*factorial(num-1);

}

function factorial1(num){

    if(num<=1) return 1;

    else return num*arguments.callee(num-1);

}

var factorial2=(function f(num){

    if(num<=1) return 1;

    else return num*f(num-1);

})

console.log(factorial(5));

console.log(factorial1(5));

console.log(factorial2(5));

(2)闭包

闭包会携带包含它的函数的作用域,所以会比其他函数占用更多的内存,过度使用闭包会导致内存占用过度。

function f1 ()

{

var n =999;

function f2 ()

{

console.log(n); 

 }

return f2;

}

var result = f1();

result();// 999

闭包就是函数f2,即能够读取其他函数内部变量的函数。由于在 JavaScript 语言中,只有函数内部的子函数才能读取内部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。闭包最大的特点,就是它可以“记住”诞生的环境,比如f2记住了它诞生的环境f1,所以从f2可以得到f1的内部变量。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。

立即调用函数表达式:

(function(){/* code */}());

// 或者(function(){/* code */})();

20.间歇调用和超时调用

超时调用

var timeout=setTimeout(function(){

alert('hi');

},1000);

取消超时调用

clearTimeout(timeout);

间歇调用

var interval=setInterval(function(){

alert('hi')

},1000);

//取消间歇调用

clearInterval(interval)

13.加法运算

如果运算子是对象,必须先转成原始类型的值,然后再相加。规则如下所示:首先,自动调用对象的valueOf方法,一般来说,对象的valueOf方法总是返回对象自身,这时再自动调用对象的toString方法,将其转为字符串。  但是如果运算子是一个Date对象的实例,那么会优先执行toString方法。

14.余数运算符

运算结果的正负号由第一个运算子的正负号决定

15.数值运算符+

将任何值转换成数值

16.指数运算符**

右结合,先进行最右边的计算

17.相等运算符

+0===-0

对于两个对象的比较,严格相等运算符比较的是地址,而大于或小于运算符比较的是值。

==

原始类型比较会先转换成数值再进行比较

对象与原始类型值比较

对象与数值比较时,对象转换成数值

对象与字符串比较时,对象转换成字符串

对象与布尔值比较时,两边都转换成数值

undefined与null和其他类型相比时,结果都为false,它们互相比较时结果为true


18.取反运算符!

不管什么类型的值,经过取反运算,都变成布尔值

19.且运算符 &&

如果第一个运算子的布尔值为true,则返回第二个运算子的值(注意是值,不是布尔值);如果第一个运算子的布尔值为false,则直接返回第一个运算子的值,且不再对第二个运算子求值。

20.或运算符||

如果第一个运算子的布尔值为true,则返回第一个运算子的值,且不再对第二个运算子求值;如果第一个运算子的布尔值为false,则返回第二个运算子的值。

21.二进制或运算符

位运算只对整数有效,遇到小数时,会将小数部分舍去,只保留整数部分。所以,将一个小数与0进行二进制或运算,等同于对该数去除小数部分,即取整数位。

22.异或运算符

“异或运算”有一个特殊运用,连续对两个数a和b进行三次异或运算,a^=b; b^=a; a^=b;,可以互换它们的值。这意味着,使用“异或运算”可以在不引入临时变量的前提下,互换两个变量的值。

23.void运算符

执行一个表达式,不返回任何值,或者说返回undefined

24.右结合的运算符

赋值运算符  三元运算符   指数运算符


28.js获取URL参数的方法

split拆分法

function request(){

var  url=location.search;

var request=new Object();

if(url.indexOf("?")!=-1){

var str=url.str(1);

var strs=str.split("&");

for(var i=0;i<strs.length;i++){

 requst[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);

}

}

return request;

}

29.面向对象——设计一个超市对象

一家超市,一个出口,一个入口,多个收银台,可以提供微信、支付宝等支付手段

30数组降维

return Array.prototype.concat.apply([ ],arr);

31.伪数组转换为数组

var arr = Array.prototype.slice.call(oldarr);

var arr=Array.from(oldarr);

32代码回收规则如下:

1)全局变量不会被回收。

2)局部变量会被回收,也就是函数一旦运行完以后,函数内部的东西都会被销毁。

3)只要被另外一个作用域所引用就不会被回收

33.正则表达式:^ 以什么开头,$以什么结尾;*任意多次;|或的意思;()组;[]集合

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,289评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,968评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 171,336评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,718评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,734评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,240评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,631评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,599评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,139评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,166评论 3 345
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,286评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,917评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,604评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,075评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,205评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,814评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,351评论 2 365

推荐阅读更多精彩内容