javascript基础(入门),外包华为前端工程师面试题

对象

JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。

var xiaoming = {

name: ‘小明’,

birth: 1990,

school: ‘No.1 Middle School’,

height: 1.70,

weight: 65,

score: null

};

JavaScript用一个{…}表示一个对象,键值对以xxx: xxx形式申明,用,隔开。注意,最后一个键值对不需要在末尾加,,如果加了,有的浏览器(如低版本的IE)将报错。

访问属性是通过.操作符完成的,但这要求属性名必须是一个有效的变量名。如果属性名包含特殊字符,就必须用’'括起来

也可以用xiaohong[‘name’]来访问xiaohong的name属性,不过xiaohong.name的写法更简洁

JavaScript规定,访问不存在的属性不报错,而是返回undefined:

由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性:

var xiaoming = {

name: ‘小明’

};

xiaoming.age; // undefined

xiaoming.age = 18; // 新增一个age属性

xiaoming.age; // 18

delete xiaoming.age; // 删除age属性

xiaoming.age; // undefined

delete xiaoming[‘name’]; // 删除name属性

xiaoming.name; // undefined

delete xiaoming.school; // 删除一个不存在的school属性也不会报错

如果我们要检测xiaoming是否拥有某一属性,可以用in操作符:

‘name’ in xiaoming; // true

‘grade’ in xiaoming; // false

不过要小心,如果in判断一个属性存在,这个属性不一定是xiaoming的,它可能是xiaoming继承得到的:

‘toString’ in xiaoming; // true

因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以xiaoming也拥有toString属性。

要判断一个属性是否是xiaoming自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法:

var xiaoming = {

name: ‘小明’

};

xiaoming.hasOwnProperty(‘name’); // true

xiaoming.hasOwnProperty(‘toString’); // false

条件判断

JavaScript使用if () { … } else { … }来进行条件判断

如果语句块只包含一条语句,那么可以省略{}

JavaScript把null、undefined、0、NaN和空字符串’'视为false,其他值一概视为true,因此上述代码条件判断的结果是true。

循环

JavaScript的循环有两种,一种是for循环,通过初始条件、结束条件和递增条件来循环执行语句块:

for … in

for循环的一个变体是for … in循环,它可以把一个对象的所有属性依次循环出来:

var o = {

name: ‘Jack’,

age: 20,

city: ‘Beijing’

};

for (var key in o) {

console.log(key); // ‘name’, ‘age’, ‘city’

}

要过滤掉对象继承的属性,用hasOwnProperty()来实现:

var o = {

name: ‘Jack’,

age: 20,

city: ‘Beijing’

};

for (var key in o) {

if (o.hasOwnProperty(key)) {

console.log(key); // ‘name’, ‘age’, ‘city’

}

}

由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for … in循环可以直接循环出Array的索引:

var a = [‘A’, ‘B’, ‘C’];

for (var i in a) {

console.log(i); // ‘0’, ‘1’, ‘2’

console.log(a[i]); // ‘A’, ‘B’, ‘C’

}

请注意,for … in对Array的循环得到的是String而不是Number。

while

for循环在已知循环的初始和结束条件时非常有用。而上述忽略了条件的for循环容易让人看不清循环的逻辑,此时用while循环更佳。

while循环只有一个判断条件,条件满足,就不断循环,条件不满足时则退出循环。比如我们要计算100以内所有奇数之和,可以用while循环实现:

var x = 0;

var n = 99;

while (n > 0) {

x = x + n;

n = n - 2;

}

x; // 2500

在循环内部变量n不断自减,直到变为-1时,不再满足while条件,循环退出。

do … while

最后一种循环是do { … } while()循环,它和while循环的唯一区别在于,不是在每次循环开始的时候判断条件,而是在每次循环完成的时候判断条件

var n = 0;

do {

n = n + 1;

} while (n < 100);

n; // 100

用do { … } while()循环要小心,循环体会至少执行1次,而for和while循环则可能一次都不执行。

函数定义和调用

请注意,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑。

如果没有return语句,函数执行完毕后也会返回结果,只是结果为undefined。

arguments

JavaScript还有一个免费赠送的关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数

实际上arguments最常用于判断传入参数的个数。你可能会看到这样的写法:

// foo(a[, b], c)

// 接收2~3个参数,b是可选参数,如果只传2个参数,b默认为null:

function foo(a, b, c) {

if (arguments.length === 2) {

// 实际拿到的参数是a和b,c为undefined

c = b; // 把b赋给c

b = null; // b变为默认值

}

// …

}

要把中间的参数b变为“可选”参数,就只能通过arguments判断,然后重新调整参数并赋值。

rest参数

由于JavaScript函数允许接收任意个参数,于是我们就不得不用arguments来获取所有参数:

function foo(a, b) {

var i, rest = [];

if (arguments.length > 2) {

for (i = 2; i<arguments.length; i++) {

rest.push(arguments[i]);

}

}

console.log('a = ’ + a);

console.log('b = ’ + b);

console.log(rest);

}

为了获取除了已定义参数a、b之外的参数,我们不得不用arguments,并且循环要从索引2开始以便排除前两个参数,这种写法很别扭,只是为了获得额外的rest参数,有没有更好的方法?

ES6标准引入了rest参数,上面的函数可以改写为:

function foo(a, b, …rest) {

console.log('a = ’ + a);

console.log('b = ’ + b);

console.log(rest);

}

foo(1, 2, 3, 4, 5);

// 结果:

// a = 1

// b = 2

// Array [ 3, 4, 5 ]

foo(1);

// 结果:

// a = 1

// b = undefined

// Array []

rest参数只能写在最后,前面用…标识,从运行结果可知,传入的参数先绑定a、b,多余的参数以数组形式交给变量rest,所以,不再需要arguments我们就获取了全部参数。

如果传入的参数连正常定义的参数都没填满,也不要紧,rest参数会接收一个空数组(注意不是undefined)。

浏览器对象

window

window对象不但充当全局作用域,而且表示浏览器窗口。

innerWidth和innerHeight属性,可以获取浏览器窗口的内部宽度和高度。

内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高

outerWidth和outerHeight属性,可以获取浏览器窗口的整个宽高。

navigator

navigator对象表示浏览器的信息,最常用的属性包括:

navigator.appName:浏览器名称;

navigator.appVersion:浏览器版本;

navigator.language:浏览器设置的语言;

navigator.platform:操作系统类型;

navigator.userAgent:浏览器设定的User-Agent字符串。

请注意,navigator的信息可以很容易地被用户修改

screen

screen对象表示屏幕的信息,常用的属性有:

screen.width:屏幕宽度,以像素为单位;

screen.height:屏幕高度,以像素为单位;

screen.colorDepth:返回颜色位数,如8、16、24。

location

location对象表示当前页面的URL信息。

例如,一个完整的URL:

http://www.example.com:8080/path/index.html?a=1&b=2#TOP

可以用location.href获取。要获得URL各个部分的值,可以这么写:

location.protocol; // ‘http’

location.host; // ‘www.example.com

location.port; // ‘8080’

location.pathname; // ‘/path/index.html’

location.search; // ‘?a=1&b=2’

location.hash; // ‘TOP’

要加载一个新页面,可以调用location.assign()。如果要重新加载当前页面,调用location.reload()方法非常方便。

history

history对象保存了浏览器的历史记录,JavaScript可以调用history对象的back()或forward (),相当于用户点击了浏览器的“后退”或“前进”按钮。

document

document对象表示当前页面。由于HTML在浏览器中以DOM形式表示为树形结构,document对象就是整个DOM树的根节点。

document的title属性是从HTML文档中的xxx读取的,但是可以动态改变:

document.title = ‘努力学习JavaScript!’;

请观察浏览器窗口标题的变化。

要查找DOM树的某个节点,需要从document对象开始查找。最常用的查找是根据ID和Tag Name

我们先准备HTML数据:

摩卡
热摩卡咖啡
酸奶
北京老酸奶
果汁
鲜榨苹果汁

用document对象提供的getElementById()和getElementsByTagName()可以按ID获得一个DOM节点和按Tag名称获得一组DOM节点:

var menu = document.getElementById(‘drink-menu’);

var drinks = document.getElementsByTagName(‘dt’);

var i, s, menu, drinks;

menu = document.getElementById(‘drink-menu’);

menu.tagName; // ‘DL’

drinks = document.getElementsByTagName(‘dt’);

s = ‘提供的饮料有:’;

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

s = s + drinks[i].innerHTML + ‘,’;

}

console.log(s);

摩卡

热摩卡咖啡

酸奶

北京老酸奶

果汁

鲜榨苹果汁

document对象还有一个cookie属性,可以获取当前页面的Cookie。

Cookie是由服务器发送的key-value标示符。因为HTTP协议是无状态的,但是服务器要区分到底是哪个用户发过来的请求,就可以用Cookie来区分。当一个用户成功登录后,服务器发送一个Cookie给浏览器,例如user=ABC123XYZ(加密的字符串)…,此后,浏览器访问该网站时,会在请求头附上这个Cookie,服务器根据Cookie即可区分出用户。

Cookie还可以存储网站的一些设置,例如,页面显示的语言等等。

JavaScript可以通过document.cookie读取到当前页面的Cookie:

document.cookie; // ‘v=123; remember=true; prefer=zh’

由于JavaScript能读取到页面的Cookie,而用户的登录信息通常也存在Cookie中,这就造成了巨大的安全隐患,这是因为在HTML页面中引入第三方的JavaScript代码是允许的:

如果引入的第三方的JavaScript中存在恶意代码,则www.foo.com网站将直接获取到www.example.com网站的用户登录信息。

为了解决这个问题,服务器在设置Cookie时可以使用httpOnly,设定了httpOnly的Cookie将不能被JavaScript读取。这个行为由浏览器实现,主流浏览器均支持httpOnly选项,IE从IE6 SP1开始支持。

为了确保安全,服务器端在设置Cookie时,应该始终坚持使用httpOnly。


DOM操作
  1. 更新DOM

拿到一个DOM节点后,我们可以对它进行更新。可以直接修改节点的文本,方法有两种:

  • 一种是修改innerHTML属性

这个方式非常强大,不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树:

// 获取

var p = document.getElementById(‘p-id’);

// 设置文本为abc:

p.innerHTML = ‘ABC’; //

ABC

// 设置HTML:

p.innerHTML = ‘ABC RED XYZ’;

//

的内部结构已修改

用innerHTML时要注意,是否需要写入HTML。如果写入的字符串是通过网络拿到了,要注意对字符编码来避免XSS攻击。

  • 第二种是修改innerText或textContent属性

这样可以自动对字符串进行HTML编码,保证无法设置任何HTML标签:

// 获取

var p = document.getElementById(‘p-id’);

// 设置文本:

p.innerText = ‘’;

// HTML被自动编码,无法设置一个

//

<script>alert(“Hi”)</script>

两者的区别在于

读取属性时,innerText不返回隐藏元素的文本,而textContent返回所有文本。另外注意IE<9不支持textContent。

修改CSS也是经常需要的操作。DOM节点的style属性对应所有的CSS,可以直接获取或设置。因为CSS允许font-size这样的名称,但它并非JavaScript有效的属性名,所以需要在JavaScript中改写为驼峰式命名fontSize:

// 获取

var p = document.getElementById(‘p-id’);

// 设置CSS:

p.style.color = ‘#ff0000’;

p.style.fontSize = ‘20px’;

p.style.paddingTop = ‘2em’;

  1. 插入DOM

当我们获得了某个DOM节点,想在这个DOM节点内插入新的DOM,应该如何做?

  • 如果这个DOM节点是空的,例如,<div></div>,那么,直接使用innerHTML = '<span>child</span>'就可以修改DOM节点的内容,相当于“插入”了新的DOM节点。

  • 如果这个DOM节点不是空的,那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点。

有两个办法可以插入新的节点。一个是使用appendChild,把一个子节点添加到父节点的最后一个子节点。例如:

JavaScript

Java

Python

Scheme

<p id="js">JavaScript</p>添加到<div id="list">的最后一项:

var

js = document.getElementById(‘js’),

list = document.getElementById(‘list’);

list.appendChild(js);

现在,HTML结构变成了这样:

Java

Python

Scheme

JavaScript

因为我们插入的js节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。

更多的时候我们会从零创建一个新的节点,然后插入到指定位置:

var

list = document.getElementById(‘list’),

haskell = document.createElement(‘p’);

haskell.id = ‘haskell’;

haskell.innerText = ‘Haskell’;

list.appendChild(haskell);

这样我们就动态添加了一个新的节点:

Java

Python

Scheme

Haskell

动态创建一个节点然后添加到DOM树中,可以实现很多功能。举个例子,下面的代码动态创建了一个<style>节点,然后把它添加到<head>节点的末尾,这样就动态地给文档添加了新的CSS定义:

var d = document.createElement(‘style’);

d.setAttribute(‘type’, ‘text/css’);

d.innerHTML = ‘p { color: red }’;

document.getElementsByTagName(‘head’)[0].appendChild(d);

可以在Chrome的控制台执行上述代码,观察页面样式的变化。

insertBefore

如果我们要把子节点插入到指定的位置怎么办?

可以使用parentElement.insertBefore(newElement, referenceElement);,子节点会插入到referenceElement之前。

还是以上面的HTML为例,假定我们要把Haskell插入到Python之前:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

❤️ 谢谢支持

喜欢的话别忘了 关注、点赞哦~。

前端校招面试题精编解析大全

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-JbpHX2PX-1712677682569)]
[外链图片转存中…(img-GfXaZ4ag-1712677682569)]
[外链图片转存中…(img-61ctqhJ2-1712677682570)]
[外链图片转存中…(img-1uzav9QM-1712677682570)]
[外链图片转存中…(img-QEKlqZSb-1712677682571)]
[外链图片转存中…(img-iCrlK56D-1712677682571)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-TcO2HFCf-1712677682572)]

❤️ 谢谢支持

喜欢的话别忘了 关注、点赞哦~。

[外链图片转存中…(img-9H9QIC6Q-1712677682572)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-x9bBBalm-1712677682572)]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值