JS内置对象,函数与作用域

1.JavaScript基于对象的语言

JavaScript和PHP不一样的地方在于:

  • PHP是面向对象语言,先有类再实例化对象;
  • JavaScript是基于对象的语言,也就是说JavaScript是由很多内置的对象组成的编程语言;


    JavaScript的主要内置对象

1.1数组对象

对象主要是由属性、方法组成的,所以学习数组对象就是学习数组对象提供的属性和方法;

  • length属性,获得数组元素的个数
length属性获取数组元素的个数
  • concat:连接数组生成新的数组
concat属性连接数组生成新的数组
  • join,使用指定的分隔符将数组连接成字符串
join使用特定的分隔符将数组连接成字符串
  • push、pop:分别表示向数组末尾添加元素、删除末尾的元素
分别两数组末尾添加元素,删除末尾元素
  • shift、unshift分别表示删除数组第一个元素、向数组开头添加一个元素
添加数组第一个元素,删除数组第一个元素
  • reverse,颠倒数组顺序
颠倒数组元素的顺序
  • slice(),截取数组元素,并将截取的部分返回
    参数1:开始的索引位置
    参数2:结束的索引


    截取字符串
  • splice() 删除数组元素,这个方法在执行时返回的是删除的数组元素
    参数1:开始的索引位置
    参数2:删除的元素个数
    参数3:可选的,如果有参数3,表示使用参数3代替删除的那些元素


    splice方法比slice方法要强大一些
  • toString(), 将数组转换为字符串,该结果的返回值是修改后的字符串
数组转换为字符串,但是方法执行后要接收一下

1.2字符串对象

  • indexOf(),获得某个字符在字符串整体中第一次出现的索引
  • lastIndexOf(),获得某个字符在字符串整体中最后一次出现的索引
查询某个字符在字符串中首次,末次出现的索引位置
  • split(),根据指定的分隔符,将字符串拆分成数组
    参数1:分隔符号
    参数2:限制返回的结果数量
split是经常使用的方法
  • replace,字符串替换
    参数1:正则表达式
    参数2:替换的结果
字符串替换
  • match()方法,用来根据正则表达式进行筛选
注意match方法是比较常用的利用正则表达式来匹配字符串的方法
  • charAt(),用来获得在指定索引位置的字符是什么?
    参数:索引位置
查找在指定索引位置的字符是什么
  • slice,字符串截取
    参数1:开始的索引位置
    参数2:结束的索引位置
不包括包含位置
  • substr()
    参数1:开始的索引位置,如果正数从0开始;如果是负数,从后面向前面数
    参数2:截取的长度
要注意负数的情况
  • toLowerCase(),将字符串转换成小写
    toUpperCase(),将字符串转换成大写
将字符串转换为大写或者小写

1.3数学对象

JavaScript给我们提供的用来进行数学计算的对象,Math

  • Math.abs(),计算一个数值的绝对值,例如 -9的绝对值就是:9


    计算一个数值的绝对值
  • Math.ceil(),向上取整,进一取整


    要注意负数的情况
  • Math.floor(),向下取整

数字向下取整
  • Math.round(),四舍五入取整
四舍五入
  • max(),获得最大值
    min(),获得最小值
取最大最小值
  • Math.pow(x,y)计算x的y次方
计算某数的次方
  • Math.sqrt(),返回数值的平方根
返回数值的平方根

Math.random(),返回0-1之间的小数,这是js中取随机数的一种方法

1.4日期对象

说明:日期对象是JavaScript封装的用来操作日期、时间的对象
通过new Date()获得日期对象

  • getFullYear(),获得年份
    getMonth(),获得当前的月份
    getDate()获得当前的日期
    getHours()获得当前的时间
    getMinutes()获得当前的分钟
    getSeconds()获得当前的秒数
日期时间
  • getDay(),获得当前是星期几?
获取当前是星期几
  • getMiliseconds()获得当前时间的毫秒部分:1000毫秒==1秒
毫秒部分

\

  • getTime(),获得当前的时间戳(单位毫秒)php时间戳的单位是(秒)
  • toLocaleString(),将日期对象转换成本地时间格式
  • 设置日期:
    setFullYear(),设置年份
    setMonth(),设置月份
    setDate(),设置日期
    获得上个月1号是星期几?
image.png

getDay()返回的是0-6的数字,分别代表了0为星期日,6为星期六;

1.5正则表达式对象

这个在正则表达式,我有做详细的论述

1.6DOM对象

这个在DOM操作这章我有做详细的论述

1,7BOM对象

BOM,Browser Object Model,浏览器对象模型,独立于内容之外的,和浏览器进行交互的对象(前进、后退、地址栏、浏览器本身一些信息等)
BOM这个浏览器对象模型给我提供了如下子对象和浏览器进行交互:

  • location对象,操作浏览器地址栏
location对象操作浏览器的地址
  • history对象,操作浏览器历史记录(前进、后退、刷新)
    history.go(-1),后退1步
    history.go(-2),表示后退2步
    ....
    history.go(1),前进1步
    history.go(0):刷新页面
    ....
    history.forward():前进一步
    history.back():后退1步

  • screen对象,获得屏幕分辨率

要注意可用宽高和实际宽高的区别
  • navigator对象,获得浏览器本身的信息
    appName: 返回浏览器内核名称
    appVersion: 返回浏览器和平台的版本信息
    platform: 返回运行浏览器的操作系统平台
    userAgent: 返回由客户机发送服务器的 user-agent 头部的值
这部分内容了解即可,不必过于深入

1.8 Window对象

window,指的是浏览器窗口,也是javascript的一个顶层对象,该对象包括DOM
、BOM,也就是说:DOM对象、BOM对象都是window的子对象

window对象是js的顶层对象

除了DOM、BOM之外,window对象还提供了一些方法供我们使用:

  • alert():弹出警告框

  • confirm(),弹出一个确认框
    参数:弹出框显示的内容
    返回布尔值,点击确定返回true,点击取消返回false


如果点击确定,则返回true,如果点击取消则返回false

  • prompt(),弹出一个输入框
    //参数1:在输入框提示的信息
    //参数2:默认值
    //返回值:点击确定获得输入框的内容;点击取消返回null
弹出一个输入框
  • setInterval,设置计时器(定时炸弹),每间隔指定的时间就执行一次
  • clearInterval,清除计时器
    //开启一个计时器,每间隔1秒执行一次
    //参数1:执行的函数体
    //参数2:间隔的时间,单位是毫秒
    //返回值:id,将来删除这个计时器的标记
  • setTimeout,设置延迟执行,延迟指定的时间执行一次
  • clearTimeout,清除延迟执行

<h1>复习部分</h1>
<h1>1.什么是变量的声明前置?什么是函数的声明前置?</h1>
所谓变量提升是指javaScript引擎的一种工作方式,先解析代码,获取所有声明的变量,之后再一行一行的运行,因此我们在js中先声明变量,再给变量赋值,其运行机制是先把变量的声明语句提升到代码的头部,相当于在代码的预执行阶段,变量就已经在头部执行了,并赋值为undefined;
而函数声明前置,则是在函数预执行阶段,将函数声明语句提到代码头部执行,那么该函数实际在代码正式执行之前就已经声明过了,因此在js中,调用函数语句可以写在函数声明语句的前面.

<h1>2.函数声明和函数表达式有什么区别?</h1>
<h3>首先明白怎么定义函数?</h3>
定义函数的方法有三种:

  • 1.函数声明(Function Declaration)
  • 2.函数表达式(Function Expression)
    1. new function 构造函数,这种方式不推荐使用;

函数声明语法格式如下:
function functionName(){ statement; } printName();

函数声明的重要特征之一是<b>函数声明提升</b>,意思是执行代码之前会读取函数声明,这也就意味着函数声明可以放在调用它的语句后面,如下:
sayHi(); function sayHi(){ alert("Hi"); }
结果是返回弹窗Hi.

函数表达式语法格式如下:
var printName = function(){ console.log('Byron'); };

函数表达式的形式看起来似乎是一个常规的变量赋值语句,即将函数作为一个值赋给变量,同样的也能够将函数作为其他函数的值返回.

<h3>那么函数表达式与函数声明有什么区别了?</h3>

  • 函数表达式可以没有函数名,这种情况创建的函数称之为匿名函数;函数声明必须要有函数名,我们试试看

声明函数时,不设置函数名会提示语法错误;

  • 函数表达式与函数声明的最重要区别就在于函数声明会提升
    因为函数声明会提升,在执行代码之前会读取函数声明,想当于在代码执行之前,函数声明已经执行过了,而函数表达式则是代码执行到函数表达式之后再进行执行.

<h1>3.arguments 是什么?</h1>
在函数内部可以使用arguments对象获取到该函数的所有传入参数:

<h1>4.函数的"重载"怎样实现?</h1>
在JavaScript中没有函数重载的概念,函数通过名字确定唯一性,参数不同也被认为是相同的函数,后面的覆盖前面的.
可以在函数体针对不同的参数调用执行相应的逻辑。如下所示:
`function printPeopleInfo(name, age, sex){
if(name){
console.log(name);
}

if(age){
    console.log(age);
}

if(sex){
    console.log(sex);
}

}
printPeopleInfo('Byron', 26);
printPeopleInfo('Byron', 26, 'male');`

<h1>5.立即执行函数表达式是什么?有什么作用</h1>
立即执行函数表达式就是(function(){})()
使用立即执行函数表达式的作用是隔离变量,防止全局变量被污染;

<h1>6.求n!,用递归来实现</h1>

<h1>7.以下代码输出什么?</h1>


输出结果应该是:
//name:饥人谷; age:2; sex:男;name:valley;
//name:小谷; age:3; sex: undefined;name:valley;
//name:男;age: undefined; sex: undefined; name: valley;

<h1>8.写一个函数,返回参数的平方和?</h1>


平方和函数如下:

<h1>9. 如下代码的输出?为什么?</h1>

  • 应该是输出undefined 以及报错,原因在于:变量提升,a由于提到代码头部,被赋值undefined,因此输出undefined,而b未定义,因此会报错;

<h1>10. 如下代码的输出?为什么</h1>

  • 由于函数声明提升,而函数表达式不会提升,因此在代码预执行阶段,函数声明已经提升至代码头部,接下来执行阶段,sayName('world')输出helloworld,而到了执行sayAge(10)阶段,由于函数表达式相当于还未声明,因此会报错,这个函数尚不存在!

<h1>11. 如下代码输出什么? 写出作用域链查找过程伪代码</h1>

1.全局作用域:
globalContext = {
    AO: {
        x: 10;
        foo: function;
        bar: function;
    }
    Scope: null;
}
//声明foo时,得到scope属性
foo.[[scope]] = globalContext.AO;
//声明bar时,得到scope属性
bar[[scope]] = globalContext.AO;

2.当调用bar()时,进入bar的执行上下文
barContext = {
    AO:{
        x: 30;
    }
    Scope: bar.[[scope]]// bar[[scope]] = globalContext.AO
}

3.调用foo(),先从bar执行上下文的活动变量(AO)中找,找不到再从bar.[[scope]]中找,找到后进行调用
4.调用foo(),进入foo的执行上下文
fooContext{
    AO{
        null
    }
    Scope: foo.[[scope]]//foo.[[scope]]=globalContext.AO;
}
5.在globaContext.AO中,x:10;因此调用foo()输出为10;
6.整体调用bar[],输出结果为10;


结果于预期一致,输出为10;

<h1>12. 如下代码输出什么? 写出作用域链查找过程伪代码</h1>

1.全局作用域
globalContext{
    AO{
        x:10;
        bar: function;
    }
    Scope: null
}
//声明函数bar得到Scope属性
bar[[scope]] = globalContext.AO;
2.执行bar(),进入bar的执行上下文
bar.Context{
    AO{
        x: 30;
        foo : function;
    }
    Scope: bar[[scope]]//bar[[scope]]=globalContext.AO
        }
//声明函数foo得到其Scope属性
foo[[scope]] = bar.context.AO;

3.执行bar()时,调用foo(),这时进入foo的执行上下文
foo.Context{
    AO{
        null;
    }
    Scope: foo.[[scope]];//foo.[[scope]]=bar.context.AO
}
4.执行console.log(x),x从当前foo.Context.AO中查找,无果,从foo.[[scope]]中查找,实质上就是从bar.Context.AO中查找,查到x=30,因此输出结果应该为30;


如同预期输出结果为30;

<h1>13. 以下代码输出什么? 写出作用域链的查找过程伪代码</h1>

  1.全局作用域
globalContext{
    AO{
        x :10;
        bar : function;
    }
    Scope: null;
}
//声明bar函数时,bar函数得到Scope属性
bar.[[scope]] =  globalContext.AO;

2.执行bar(),进入bar的执行上下文
bar.Context{
    AO{
        x: 30;
        立即执行函数(匿名函数): function;
    }
    Scope: bar.[[scope]] //bar.Context=globalCotext.AO;
}
声明立即函数时,立即执行函数得到属性Scope
function.[[scope]] = bar.Context.AO;

3.调用立即执行函数,进入其执行上下文
function.Context{
    AO{
        null;
    }
    Scope: function.[[scope]];
}

4.执行console.log(x),x从当前执行上下文中查找,先查function.Context.AO,无果,之后从function.[[scope]]中查找,function.[[scope]]=bar.Context.AO, 从中查找查x=30;
    输出 30;       

<h1>14. 以下代码输出什么? 写出作用域链查找过程伪代码</h1>

 1.全局作用域
globalContext{
    AO{
        a: 1;
        fn : function;
        fn3 : function;
    }
    Scope: null;
}
//声明函数fn时,得到其Scope属性 
fn.[[scope]]  = globalContext.AO;
//声明函数fn3时,得到其Scope属性
fn3.[[scope]] = globalContext.AO;

2.调用fn(),进入fn的执行上下文
fnContext{
    AO{
        a:5;
        a:6;
        fn2: function;
    }
    Scope: fn.[[scope]] //fn.[[scope]] = globalContext.AO 
       }
//声明fn2,得到其属性Scope
fn2.[[scope]] = fnContext.AO;

3.执行第一个console.log(a),输出为undefined;

4.赋值操作,a=5;

5.执行第二个console.log(a),输出5;

6.a++,a =6;

7.调用fn3(),进入fn3的执行上下文
fn3Context{
    AO{
        null
    }
    Scope: fn3.[[scope]];//fn3.[[scope]]=globalContext.AO;
}

8.执行fn3内部console.log(a),a搜寻当前执行上下文,从fn3,[[scope]]中搜寻,a=1;输出1;之后执行赋值操作,a=200;调用fn3完毕

9.调用fn2(),进入fn2的执行上下文
fn2Context{
    AO{
        null
    }
    Scope: fn2.[[scope]]//fn2.[[scope]] = fnContext.AO;
}

10.执行fn2内部的console.log(a),a从当前执行上下文中搜寻,从fn2.[[scope]]中搜寻得a=6,输出5;之后赋值操作,a=20;调用fn2结束

11.执行console.log(a),输出20;调用fn()结束;

12.执行console.log(a),此时全局变量a为200;

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

推荐阅读更多精彩内容