`

京东商城前端面试小心得.

阅读更多

昨天去京东面试了一下前端.可惜没有面试成功.回来根据回忆把这次失败的经历记录下来,来让自己静下心.也可以成为别人的面试参考.

首先介绍一下我的整个面试过程下来对京东前端技术这部分的映象.在面试过程中我了解到京东的后台是用java写的,而且前后端并未实现分离,所以要想去京东面试,必须对java有一定的了解,以及java写前端的一些框架比如:SSH.以及mvc框架的实现原理和机制,这块内容虽然并未在招聘上面写明,不过如果你会这方面的内容,是一个很好很强大的加分项.

其实面试的时候的提问无非就是一些基本的html知识,和css的一些知识,然后就是js的一些基本点,和难点.

第一部分:css

在面试之前,我以为面试css会从盒模型,position和float之间的影响,动画,或者一些兼容情况来给你出难题让你来解决.但是实际情况问得都是最基本的.我记忆中,css部分问得比较少,几个方面如下:

1:css可以在html中写吗?

这个就算是最最基础的问题了,一般做前端的人都了解,在html中可以写在内联样式中(style).或者直接link引入css文件.还有一个import.有的同学可能没有听说过@import,平时只用过link.其实@import确实是不被推荐使用的,因为在一些浏览器中会有兼容性问题,比如ie5;另一个原因:link是xhtml标签啊,除了能引入css样式文件之外,还能定义RSS,rel等,功能很强大的;最后一个原因:在加载网页的时候link是随着网页的加载同步进行的,而@import是网页加载完毕之后进行的.对用户体验差别很大的.

2:css的优先级.

这个也简单,!important>内联样式>外联样式(id>class>tag);

3:css优化有几种方式.

这个问题在实际项目中其实是处理过的,但是回答的时候,不知道怎么去表达.回来之后,我从网上查找相关资料,先总结如下:

第一点:从实际出发,从用户角度出发.如果一些很炫的技术,在实际用户体验时并不好,或者根本不需要.那么还是舍去比较好一点.

第二点:提高css的加载性能.

严格让样式和结构分离,也就是说在head中引入css,不要写内联样式.减小css文件的大小,尽可能利用html缓存.也可以对css进行压缩来减少它的体积(这个应该是常用的).能用一句话解决的样式就不要多写.

第三点:合理使用选择器

尽量不要使用通配符选择器.

*{}

 能继承的属性就不要再在子元素中重复书写了.能继承的属性如下:

font-size font-family color, UL LI DL DD DT;

 不能继承的属性如下:

border padding margin width height ;

 第四点:提高渲染性能

对与浮动和定位要考虑再三之后再使用.最好有css书写规范.

关于位置的css尽量放在最前面,之后是大小,文字,背景边框,等.

第五点:要利于后期的维护.

第二部分:html

1.平时用到html5的那些特性.

我平是用到的最多的其实就是新的标签和语义化了.在html5的规范中,其实对行内元素和快级元素的分类已经弱化了.或者说没有了.平时用到的语义化标签如下:

<hx>
<ul><li><ol>
<p>
<em>
<strong>
<table>
<site>
<blockquote>块引用
<header>
<footer>
<article>
<section>
<nav>
<aside>

//下面是表单的一些东西
<table>使用场景是表状数据
<label>输入控件定义文本标签
<fieldset>把表格中的相关控件集中起来
<legend>定义控件组的标题

 2为什么要html5语义化开发?

第一点:更容易让结构和样式分离,可以用正确的标签来处理正确的事情,从而使浏览器,和搜索引擎解析方便.

第二点:在所有的css样式文件不存在的情况下,对网页的结构也是一目了然;

第三点:搜索引擎的爬虫依赖于html标记去确认上下文以及各个关键字的权重,从而有利于搜索引擎的优化.

第三部分:js

1.js的this指针理解

在这里我引用一个别的面试题来更好的说明一下关于this指针的问题(引用自一个微信公众号的内容,名字是:web前端课程):

function Foo () {
    getName = function (){
        alert(1)
    };
    return this;
};
Foo.getName = function (){
    alert(2);
};
Foo.prototype.getName = function (){
    alert(3);
};
var getName =function (){
    alert(4);
};
function getName(){
    alert(5);
}

 通过以下方式进行调用:

 

 

Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

 最后的结果是:2,4,1,1,2,3,3.

 

其实可以从答案来说明this的指向;

第一问的Foo.getName();其实就是在调用Foo函数的属性getName(),答案其实就是该函数的输出:2

第二问的getName();就是在调用getName这个函数.输出:4;但是为什么不是5呢?这其实和var这个声明(所有的声明变量或者函数都会提升到当前函数的顶部)有关.下面是整个的处理过程.

 


//声明变量和函数 var getName;//声明变量 function getName () { alert(5); }//声明函数 function Foo () { getName = function (){ alert(1); }   return this; } Foo.getName = function (){ alert(2); }; Foo.prototype.getName()=function () { alert(3) }; getName = function (){ alert(4) };//赋值操作.(其实是覆盖了alert(5));

 所以根据这个过程来看.getName()最后的结果就是4;

第三问的Foo().getName();执行过程是这样的:首先执行Foo()函数,发现Foo函数的作用域中并没有声明getName;所以会在外层作用域中查找getName变量,发现在外层作用域中有该变量的声明(如果没有会一直网上找,找到window还没有就会自己创建),于是对该变量进行赋值操作,也就是

getName = function () {
    alert(1);
}

 ,到这里就该执行Foo函数的renturn this 语句,这里的this由于是直接的调用,所以调用结果就是window,

 

所以,现在Foo().getName()函数就相当于,window.getName();而由于上面的赋值操作,所以window.getName()的结果就是1

第四问的getName函数,相当于window.getName().也就是第三问的结果,所以是1

第五问的new Foo.getName();其实就是在调用Foo.getName()这个函数,结果是2.(因为'.'运算符的优先级高于'new').

第六问的new Foo().getName(),因为'()'运算符的优先级高于'.'高于'new';所以实际执行顺序是这样的:(new Foo()).getName();   js的构造函数是可以有返回值,也可以没有的,如果没有返回值则返回实例化对象,如果有返回值则判断这个返回值是不是引用的类型,对于基本的数据类型而言,返回实例化对象;对于引用的类型而言(注意:对象也是引用的类型)则返回该引用类型;

 

function test (){

}
new test();//结果是test{}

 

function test (){
return 0}
new test () {
}//结果是test{};

 

function test () {
    return {a:0}
}

new test();//结果是{a:0}

所以new Foo()的结果是该实例化对象(return this )(this 就指向该实例化对象,而不是window,因为new改变了this 的指向);所以(new Foo()).getName()就相当于 Foo.prototype.getName().所以结果是3;

 

第七问的new new Foo().getName();的执行结果其实就相当于new ((new Foo()).getName()),其实就相当于new(Foo.prototype.getName());所以结果就是3;

2.对js或者jQuery的事件代理的了解;

其实在遇到这个问题的时候我脑袋有点懵,因为在我以前的项目中,并没有遇到过这种事情.所以回来之后,我就对事件代理进行了了解,其实说起来也是比较容易理解的.

js的事件代理和事件委托 其实和dom树以及浏览器的事件冒泡机制有关系.简而言之就是浏览器处理dom事件的机制是:事件捕获,事件目标,事件气泡(这是标准的,ie有不同的机制).

事件捕获:当一个元素触发某个事件的时候,顶层的document对象会发出一个事件流从DOM树的节点向下面对的目标元素节点流动,直到到达触发事件的真正的节点,在此过程中事件对应的监听函数是不会起作用的;

事件目标:找到目标元素之后执行目标元素对应的处理函数,没有则不执行;

事件起泡:从目标元素开始往上层开始流动,如果中途有节点绑定了相应的事件,则触发事件.如果想阻止事件的触发,则e.stopPropagation()  (Firefox)或者e.cancelBubble=true   (IE);

它的主要用途是用于:当对很多元素添加事件的时候,我们可以把事件委托给它的父节点 来触发处理的函数,这样就减少了函数绑定的个数.

//jquery的事件代理
$(selector).delegate(childSelector,event,data,function)
//childSelector是必须的,附加事件处理程序的子元素
//event是必需的,有效事件
//data可选的,传递的数据
//必选的,事件发生时的运行的函数.

 3.对js闭包的理解

当问到这个问题的时候,我没有回答好,因为我的理解是,所有的js中所有的函数不都是闭包吗?这如何谈理解呢?

但是当我回到住的地方的时候,我才想起来,这应该是问我,词法作用域,作用域链和闭包;其实所有的js函数的确都是闭包的.它们都是对象.通常用到闭包其实就是函数套嵌多个函数的时候,也就是说,调用函数时的作用域链和定义函数时的作用域链不是同一个作用域链的时候,会出现一些问题.

说到这里就会说道变量作用域,在一些说更底层的编程语言中,比如c,一个函数的局部变量的定义以及存储都是存储在电脑的栈里,当函数返回的时候,它们就已经不存在了.但是在js中并非如此,js中的作用域其实更像一个对象列表(作用域链)没有绑定在栈,函数定义时的作用域链在函数调用的时候依然存在,每一次对js对象的调用,又会重新创建一个新的对象,去保存局部变量,然后把这个对象添加到作用域链之中.当函数返回的时候就会删除相应的对象.所以,如果没有嵌套的函数,也没有其他的引用来指向这个绑定对象的话,它就会被当成垃圾来回收处理掉.但是如果有嵌套的函数,每个嵌套的函数都有各自的作用域链,并且该作用域链指向一个变量绑定对象.当这些嵌套的函数在外部的作用域之中被保存了下来,也就是说虽然有嵌套但是没有其他的指引来指向绑定变量,这个时候,该函数和该函数指向的绑定变量一起被当作垃圾回收,所以在使用闭包的时候,这里是需要注意的地方.所以在使用闭包的时候,定义嵌套函数时,将它作为返回值返回或者存在某处的属性中,这个时候就会有外部引用指向这个嵌套的函数,就不会被当作垃圾来处理了(包括绑定的对象).

 

function counter () {

 

 

    var n = 0;
    return {
        count:function(){return n++;},
        reset:function(){n = 0;}
    }
}
var c = counter(),d = counter();
c.counter()//0
d.counter()//0
c.reset()//reset()和count()共享
d.counter()//1
c.counter()//0
//引自js权威指南

这个能很好的说明闭包.count()和reset() 都能访问到私有变量n,在每次调用count()的时候,都会重新定义一个作用域链和新的私有变量,所以,调用counter()几次就会得到几个对象,所以c和d是互不干扰的两个对象,并且拥有互不干扰的私有变量.所以各自调用count和reset并不会影响另外一个.

 

4,对js的apply(),call(),bind()的理解

在平时的工作之中遇到过使用apply的场景,是因为当时的写的api的一个方法的this指针并没有调用过来.所以用apply方法来使用的.但是当面试的时候,确实谈不了太多,因为确实是自己认识的比较少.

其实说到apply()和call(),就还得说道js语言的根本上,js是面向对象的语言,js中的任何都可以当成是对象(包括函数),当this可以更改的时候,任何函数就都可以作为任何对象的方法来调用,也就是说apply()和call()可以实现简介调用函数,即便这个函数与那个对象并没有什么关系.而call()方法与apply()方法的最直观的区别就是:call()使用它自己的实参列表当函数的实参.apply()方法要求一数组的形式传入参数.

bind()方法的主要作用是可以将函数绑定至某一个对象

function f(y){
    return this.x+y;
}
var o = {x:1};
var g = f.bind(o);
g(2)//=>3
//引自js权威指南

 

 这就是bind()的使用方法.

 

当然也可以通过apply来模仿这个方法:

function bind (f,o){]
    if(f.bind){return f.bind(o)};
    else return function (){
        return f.apply(o,arguments);
}}
//引自js权威指南

 

 但是模仿的这个方法是不能和bind方法等同的.因为bind()的实参会绑定至this.其实这也被称之为柯里化编程.

4.如何理解柯里化(curry)编程

这个在面试的时候,脑子里隐隐约约有一些映象.

curry化编程,其实就是只给函数传递一部分参数来调用它,让它返回一个函数去处理剩下的参数.

 

function curryBefore (a,b){
    if(b === undefined){
        return function (z){
              return a+z
        }else{
           reuturn a+b
        }
    }
} 

上面写的这个函数是没有curry之前的一个函数,当你调用这个函数的时候,

 

curryBefore(1,2);和curryBefore(1)(2)的调用结果是一样的.但是执行的过程不一样,第二中调用方式其实用到了闭包的特性,记录了a的值,而第一种调用方式是直接调用的else后面的表达式.那么这个curry是怎么来处理的呢?

 

//此处代码引自<<JavaScript: Novice to Ninja>>
function curry (func){
    var fixedArgs = [].slice.call(arguments,1);
    return function (){
        args = fixedArgs.concat([].slice.call(arguments))
        return func.apply(null,args);
    };
}

 下面说明curry的运行过程.

 

 

function multiplication (x,y){
   return x*y
}
course = curry(multiplication,2);
course(1);

 

 执行了course(1),其实执行了curry(multiplication,2)(1);curry通过[].slice去掉了第一个参数:

function multiplication (x,y){  return x*y},然后保留了变量x=2,返回一个新的函数,这时候传入变量y=1,

然后通过:

fixedArgs.concat([].slice.call(arguments))

 

将x和y组成一个新的数组,然后在执行multiplication.其实就是通过curry来整理参数,最后通过apply来调用.

 

 

 

 

 

 

 

 

 

 

 


 

1
0
分享到:
评论

相关推荐

    基于JavaWeb 仿360,京东商城项目设计与实现.zip

    基于JavaWeb 仿360,京东商城项目设计与实现.zip基于JavaWeb 仿360,京东商城项目设计与实现.zip基于JavaWeb 仿360,京东商城项目设计与实现.zip基于JavaWeb 仿360,京东商城项目设计与实现.zip基于JavaWeb 仿360,...

    京东金融Vue组件化实战系列课程前端面试项目冲刺.txt

    京东金融Vue组件化实战系列课程前端面试项目冲刺.txt

    238道大厂前端高频面试题.pdf

    然而,我会尝试对标题中提到的“238道大厂前端高频面试题”这一知识点进行详尽的阐述。 首先,“大厂”一词在IT行业中常用来指代大型知名互联网公司,比如阿里巴巴、腾讯、百度、京东、字节跳动等。这些公司因提供...

    北京-京东-Java中级面试真题.zip

    北京-京东-Java中级面试真题.zip 北京-京东-Java中级面试真题.zip 北京-京东-Java中级面试真题.zip 北京-京东-Java中级面试真题.zip 北京-京东-Java中级面试真题.zip

    java源码 仿360buy京东商城源码 京东JavaWeb项目源代码.zip

    java源码 仿360buy京东商城源码 京东JavaWeb项目源代码.zipjava源码 仿360buy京东商城源码 京东JavaWeb项目源代码.zipjava源码 仿360buy京东商城源码 京东JavaWeb项目源代码.zipjava源码 仿360buy京东商城源码 京东...

    京东商城价值链分析222.pptx

    "京东商城价值链分析" 京东商城价值链分析可以分为以下几个方面: 1. 战略目标:京东商城的战略目标是通过差别化战略,提供差别化的产品和服务,满足客户的需求,提高客户满意度和忠诚度。同时,京东商城也努力...

    基于Vue开发的京东商城移动前端代码

    在本项目中,我们主要探讨的是使用Vue.js框架来开发京东商城的移动前端部分。Vue.js是一个轻量级、高性能的JavaScript库,专为构建用户界面而设计,尤其适合单页面应用(SPA)。它提供了声明式的数据绑定和组件化的...

    京东商城笔记+源代码.7z

    在本资源"京东商城笔记+源代码.7z"中,你将有机会深入学习和实践Web前端开发技术,特别是与京东商城网站相关的布局设计。这个压缩包包含了一份笔记和源代码,旨在帮助开发者提升前端技能,理解大型电商网站的页面...

    京东商城的网络营销方案.pdf

    京东商城的网络营销方案.pdf

    京东商城案例分析实施报告.doc

    京东商城案例分析实施报告.doc

    jdsc.zip_jdsc京东商城_site:www.pudn.com_京东 java

    【标题】"jdsc.zip_jdsc京东商城_site:www.pudn.com_京东 java" 指的是一个关于京东商城UI设计的压缩文件,它可能包含了一系列与京东商城前端界面相关的资源,如图片、CSS样式表、JavaScript脚本、HTML模板等。...

    京东商城商家后台操作手册.doc

    京东商城商家后台操作手册.doc

    京东商城的数据库(projectsSQL.sql)

    京东商城的数据库(projectsSQL.sql),非常完整实用。

    浅谈京东商城的网络营销策略.zip

    浅谈京东商城的网络营销策略.zip

    jquery京东商城三级联动特效.rar

    在这个“jquery京东商城三级联动特效.rar”压缩包中,包含了一个实现京东商城风格的三级联动选择效果的示例。这个特效通常用于商品分类筛选,用户在选择一级分类后,二级和三级分类会随之更新,为用户提供更精确的...

    京东商城品牌架构设计建议.pptx

    【京东商城品牌架构设计建议】 在探讨京东商城的品牌架构设计时,我们首先需要理解品牌架构的概念。品牌架构是指一个企业或组织内部品牌之间的关系结构,它决定了如何在市场中定位和展示各个品牌,以及它们如何相互...

    京东商城现有物流模式出现.zip

    《京东商城现有物流模式探析》 京东商城作为中国电商巨头之一,其物流体系一直备受业界关注。京东的物流模式以其高效、快捷、精准而著称,为消费者提供了卓越的购物体验。本文将深入探讨京东商城现有的物流模式,...

    京东软件开发面试内部推荐.docx

    京东软件开发面试与招聘主要涉及多个职位,包括Android应用开发工程师、iOS开发工程师、Java开发工程师、产品经理、交互设计师(UE)和视觉设计师(UI),以及前端开发工程师。这些职位的任职要求涵盖了广泛的IT技术...

    京东商城供应商后台管理.pptx

    前端优化、推广是供应商在京东商城销售的第七步骤,旨在提高供应商的销售额。该步骤包括优化商品信息、店铺装修、商品推广等方面的优化,以提高供应商的销售额。 售后维护是供应商在京东商城销售的第八步骤,旨在...

    最新各大厂前端面试题以及答案.rar

    这份名为"最新各大厂前端面试题以及答案.rar"的压缩包文件,显然汇集了淘宝、阿里、京东、美团等知名企业的前端面试题目及参考答案,旨在帮助求职者更好地准备面试,提升通过率。下面,我们将详细探讨这些标签所涵盖...

Global site tag (gtag.js) - Google Analytics