前端精髓-笔记

react和vue的优劣
  vue: Vue.js使用HTML模板语法将DOM绑定到实例数据。Model是在数据改变时更新view的纯JavaScript对象。

    如果你喜欢用模板搭建应用(或者有这个想法),请选择Vue
    如果你喜欢简单和“能用就行”的东西,请选择Vue
    如果你想要你的应用尽可能的小和快,请选择Vue

优点:    可以快速使用,并且日益普及很容易提高高水平开发人员的满意度,
    依赖性小,性能好

缺点:    一个较新的项目 - 风险可能会更大
    部分依赖开发人员进行更新
    相比于其它框架,资源较少

react:    它专注于Model-View-Controller(MVC)开发的“View”部分,使用它可以轻松创建保留状态的UI组件。
    它是实现虚拟DOM的首选类库之一, 它的内存结构能够有效地计算差异,页面更新也更加有效。

    如果你打算构建一个大型应用程序,请选择React
    如果你想要一个同时适用于Web端和原生APP的框架,请选择React
    如果你想要最大的生态系统,请选择React
    
优点:    小巧,高效,快捷灵活简单的组件模型
    良好的文档和在线资源
    可实现服务器端渲染
    目前受欢迎,经历了快速增长

缺点:    需要学习新的概念和语法
    构建工具很重要
    需要其它类库或框架提供model和Controller部分
    与修改DOM的代码和其它类库不兼容
                        

    进制转换:如16转10:按权展开加和eg:522(16进制)=5*16^2+2*16^1+2*16^0=1314(10进制)(16进制0~9和A~E这16个字符对应10进制的0~15)
    10转16:反向取余eg:1314/16=82...2  82/16=5...2  5/16=0...5 
                            
                        前端常用:
1.常用css单位:vw屏幕宽度占比,vh表示屏幕高度占比(1vw表示宽度的1%)vmin表示占宽高中较小的比例,vmax同理可知;用此单位可实现比例响应
2.绝对定位元素居中position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;
3.line-height不是元素的直接高度,是文本之间的间距,可理解为两行文字基线之间的距离;
  line-height为行高,文本占纵向空间的原因其实是line-height,可以利用设置行高的方式将行内内容垂直居中.
4.swiper组件:实现移动端网页触摸滑动特效可选轮播效果,具体使用方法可参考swiper官网,用之前要导入swiper.css或其压缩包
5.行内元素是不支持上下方向的padding和margin
6.单位px,em,rem,vw:px为像素,em为相对父容器字体单位,rem为相对body根元素的字体单位,vw是相对视口(viewport,浏览器窗口或者手机屏幕)的宽度所占百分比

7.组选择器的权重规则判断优先级;
    内部样式>id选择器的数量 > 类、伪类、属性选择器数量 > 元素、伪元素选择器数量

8.临近兄弟元素选择符用"+"选择符:ul>li+li{left:5px}相邻两列的选择器;
  某个节点后的兄弟节点(不限定相邻)之间的选择符:"~"(波浪线)

9.反选伪类选择符:   :not(selector)

10.vertical-align:垂直对齐方式
11.html中的<sup>标签代表上标显示,如指数函数
12.linux常用命令
    cd 定位文件夹
    ls 查看当前文件夹
    ../或..返回上一级
    tail -f(日志名)查看日志内容
    如:cd ../usr/local/nginx/logs/swda
    ctrl+c暂停并重新操作,方向上+enter继续(如刷新日志)
    pwd   显示当前目录
    find  在文件系统中搜索某文件


13.css渐变:两种或多种颜色之间平滑过渡,渐变相当于图片,可以在任何使用url()值的地方使用,目前background-image支持最广

14.css颜色模式:rgba(三原色值和透明度)  hsla(色调,饱和度,亮度,透明度)

15.css渐变gradient:    
    css线性渐变:语法:background: linear-gradient(direction, color-stop1, color-stop2, ...);
            eg:
        -webkit-linear-gradient(top,#ccc,#000);

    css径向(辐射)渐变:语法:background: radial-gradient(center, shape size, start-color, ..., last-color);
             
        #grad {
              background: -webkit-radial-gradient(red 5%, green 15%, blue 60%); /* Safari 5.1 - 6.0 */
              background: -o-radial-gradient(red 5%, green 15%, blue 60%); /* Opera 11.6 - 12.0 */
              background: -moz-radial-gradient(red 5%, green 15%, blue 60%); /* Firefox 3.6 - 15 */
             background: radial-gradient(red 5%, green 15%, blue 60%); /* 标准的语法 */
        }
16.string.substring(起,终):截取字符串操作,用于提取字符串中介于两个指定下标之间的字符
   string.indexOf(搜索字符值,搜索起始索引[不必需]):方法可返回某个指定的字符串值在字符串中首次出现的位置

17.css变形-transform:2D变形函数:
    tanslate(x,y)平移2D转换,
    1*    translate3d(x,y,z)3D转换(平移),--------------------------------------重要
    translateX(x),translateY(y)只在某一个方向2D转换
    translateZ(z)在Z轴定义3D转换

    scale(x,y)2D缩放,scale3d(x,y,z)3D缩放,
    2*    scaleX(x),scaleY(y),2D方向的水平缩放
    scaleZ(z)在垂直屏幕的Z轴定义3D缩放
    
    rotate(angle)2D翻转参数为角度
    3*    rotate3D(x,y,z,angle)3D翻转
    rotateX(x,angle),rotateY(y),rotateZ(z,angle)在三个方向的--3D翻转---------重要

    skew(x-angle,y-angle)沿着 X 和 Y 轴的 2D 倾斜
    4*    skewX(angle)沿着 X 轴的 2D 倾斜
    skewY(angle)沿着 Y 轴的 2D 倾斜
    (注意:没有3D倾斜,倾斜是二维变形,不能在三维空间变形,元素可以在X轴Y轴上倾斜然后转化成3D,
        但是不能在Z轴上倾斜)
    
    5*    perspective(n)为 3D 转换元素定义透视视图(制造3D透明效果)
`    
    6*    matrix(n,n,n,n,n,n)定义 2D 转换,使用六个值的矩阵
    matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n)定义 3D 转换,使用 16 个值的 4x4 矩阵

    
    其实上述所有旋转和拉伸效果本质都是matrix()函数实现的,也就是说transform本质是matrix()或matrix3d()在起作用。
    ----------------------------------------------------------
实例:div
    {
        -ms-transform:rotate(7deg);     /* IE 9 */
        -moz-transform:rotate(7deg);     /* Firefox */
        -webkit-transform:rotate(7deg); /* Safari 和 Chrome */
        -o-transform:rotate(7deg);     /* Opera */
        transform:rotate(7deg);
    }


18.transform属性:指一组转换函数
    transform-origin属性指定元素的中心点在哪-----这是矩阵变换的一个重要的依据点
    transform-origin-z控制元素的3D中心点

    transform-style:preserve-3d让所有子元素在3d空间呈现
    transform-style:flat   默认值,表示所有子元素呈2d显示

    perspective 透视:属性定义 3D 元素距视图的距离,以像素计。该属性允许您改变 3D 元素查看 3D 元素的视图
            为该元素的子元素获得透视效果,而不是这个元素本身
            perspective 属性只影响 3D 转换元素
            建议与 perspective-origin 属性一同使用该属性,这样您就能够改变 3D 元素的底部位置。
    
    perspective-origin是3D变形中另一个重要属性,主要用来决定perspective属性的源点角度,在该位置观察好像在观察
    该元素的子元素.


19.css过渡:translation
transition属性主要包含四个属性值:
    transition-property:指定过渡或动态模拟css属性
    transition-duration:指定完成过渡所需的时间
    transition-timing-function:指定过渡函数
    transition-delay:制定过渡开始出现的延迟时间
    注意可以将transition的这四个属性并列写在一起,中间用空格而不是逗号隔开
    如:E{
        -webkit-transition:background 2s linear 2s,border-radius 3s ease-in 4s;
        transition:background 2s linear 2s,border-radius 3s ease-in 4s;
    }

因此transtion的语法为:transition:<过渡属性> <过渡时间> <过渡动画函数> <过渡延迟时间>

易混淆:transform:变换(包括位移translate,翻转rotate,缩放scale,矩阵变换matrix(变换的实质),倾斜skew)
    transition:过渡    translate:位移


20.若盒子如(div:display:inline-block;)之间margin为0仍有空隙,则将margin设为负值可抵消空隙;
    试试去掉display:inline-block后浮动排版有奇效;


21.flexbox:伸缩盒(兼容性比较好,兼容目前主流新版的浏览器)

    .box{
        display:flex;
        }

    1*若justify-content值为colum时主轴方向为纵向的

    2*justify-content内容排版:用于设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式(IE和Safri不支持此属性)

    3*display:flex(或者inline-flex)表示该容器是一个伸缩容器
    
    4*flex-wrap该属性控制flex容器是单行或者多行,同时横轴的方向决定了新行堆叠的方向。

        nowrap:flex容器为单行。该情况下flex子项可能会溢出容器,但是不会换行

        wrap: flex容器为多行。该情况下flex子项溢出的部分会被放置到新行,子项内部会发生断行
        
        wrap-reverse: 反转 wrap 排列。

    5*注意,设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。


    6*flex-container容器的属性:

                   1)flex-direction属性决定主轴的方向(即项目的排列方向)
                    .box {
                          flex-direction: row | row-reverse | column | column-reverse;
                    }

                2)flex-wrap属性用于指定弹性盒子的子元素换行方式
                flex-wrap:nowrap(不换行,伸缩元素可能会溢出容器)|wrap(换行,子元素会多行显示)|wrap-reverse(换行,且元素反转多行显示,底部显示多列,剩余的元素往上排列)

                3)flex-flow:flex-direction 和 flex-wrap 的简写

                4)justify-content属性应用在伸缩容器上,把弹性项沿着弹性容器的主轴线(main axis)对齐.
                justify-content: flex-start | flex-end | center | space-between | space-around
                
            5)align-items 设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式。
                   
            6)align-content修改 flex-wrap 属性的行为,类似align-items, 但不是设置子元素对齐,而是设置行对齐
    
    
            8)box-orient用来指定伸缩项目如何放置在伸缩容器的主轴上。值有horizental(在水平行中从左向右排列子元素),vertical,inline-axis(内联轴排列),block-axis(块状排列)
    
    
    7*弹性容器外及弹性子元素内是正常渲染的。弹性盒子只定义了弹性子元素如何在弹性容器内布局。

      弹性子元素通常在弹性盒子内一行显示。默认情况每个容器只有一行。

    

    
    8*


22.浏览器兼容问题:    这个js工具会帮你自动识别浏览器,生成对应的Css3样式前缀,这样你就可以直接当作标准属性来使 用了。

    引用方式:<script src=”http://leaverou.github.com/prefixfree/prefixfree.min.js”></script>

    该js项目地址为http://leaverou.github.com/prefixfree/。

    当一个属性成为标准,并且被Firefox、Chrome等浏览器的最新版普遍兼容的时候,我们可以去掉一个属性的浏览器前缀
    
    -webkit-(谷歌,safri),-moz-(火狐),-ms-(IE),-o-(欧朋)


23.jq中attr()和prop()方法的区别:
    例子:    $("#chk1").prop("checked") == false
        $("#chk2").prop("checked") == true

        $("#chk1").attr("checked") == undefined(有问题)
        $("#chk2").attr("checked") == "checked"
像checkbox,radio和select这样的元素,选中属性对应“checked”和“selected”,这些也属于固有属性,因此需要使用prop方法去操作才能获得正确的结果。
如果上面使用attr方法,则会出现问题


24.定位问题:父容器绝对定位,最好不能用line-height还有over-flow属性

25.盒子阴影:box-shadow:  投影方式 X轴偏移量 Y轴偏移量 阴影模糊半径 阴影扩展半径 阴影颜色;


26.$(selector).trigger('event',[params1,params2,params3...])规定被选元素要触发的事件

    这种方法可以给某函数定义回调函数如: 
        function:f1(){

                //f1的执行代码
                f1.trigger('done')
            },

        f1.on('done',f2);
    说明:f1.trigger('done')表示,执行完成后,立即触发done事件,从而开始执行f2。


27.text-overflow:clip(默认值,修剪文本)|ellipsis(显示省略符来表示被修剪文本)|string(使用给定字符串表示被修剪文本);

28.window.devicePixelRatio是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例。
    设备像素比:window.devicePixelRatio = 物理像素 / dips

    @media screen and(-webkit-min-device-pixel-ratio:2)//媒体查询屏幕的设备像素比(表示每个dip)

29.jQuery中的eq()方法:函数返回值为jQuery类型,返回封装了指定索引index处的元素的jQuery对象。
    eq()方法与:eq()选择器等价于下列代码:
        $("selector").eq(index);
        $("selector:eq(index)");最终返回的都是一个jQuery对象

30.几个高度:
    $(window).height();           //浏览器当前窗口可视区域高度 
    $(document).height();         //浏览器当前窗口文档的高度 
    $(document.body).height();    //浏览器当前窗口文档body的高度

    window.innerWidth();获取当前窗口的宽度(包含滚动条)
    $(window).width();获取当前窗口的宽度(不包含滚动条)

31.css中left,right,top,bottom;
    如:left 属性规定元素的左边缘。该属性定义了定位元素左外边距边界与其包含块左边界之间的偏移
****注意:这四个偏移属性只有在元素的position为static时不生效


32.css中margin(margin允许负值,padding不允许负值),浮动,定位的问题:
    
    ##表现
  虽然margin可以应用到所有元素,但display属性不同时,表现也不同

  【1】block元素可以使用四个方向的margin值

  【2】inline元素使用上下方向的margin值无效

  【3】inline-block使用上下方向的margin负值看上去无效

  [注意]inline-block使用上下方向的margin负值只是看上去无效,这与其默认的vertical-align:baseline有关系,当垂直对齐的属性值为其他值时,则会显示不同的视觉效果

    
    ##重叠
  margin负值并不总是后面元素覆盖前面元素,它与元素display属性有关系

  【1】两个block元素重叠时,后面元素可以覆盖前面元素的背景,但无法覆盖其内容

  【2】当两个inline元素,或两个line-block元素,或inline与inline-block元素重叠时,后面元素可以覆盖前面元素的背景和内容

  【3】当inline元素(或inline-block元素)与block元素重叠时,inline元素(或inline-block元素)覆盖block元素的背景,而内容的话, 后面的元素覆盖前面的元素

      综上所述,个人理解,在普通流布局中,浏览器将页面布局分为内容和背景,内容的层叠显示始终高于背景。
    block元素分为内容和背景,而inline元素或inline-block元素,它本身就是内容(包括其背景等样式设置)    

    ##浮动
  【1】block元素与浮动元素重叠时,其边框和背景在该浮动元素之下显示,而内容在浮动元素之上显示

  【2】inline或inline-block元素与浮动元素重叠时,其边框、背景和内容都在该浮动元素之上显示

    ##定位
  【1】定位元素(position不为static)覆盖其他元素的背景和内容

  【2】将relative属性值应用于inline元素,由于无法改变其行内元素的本质,所以其上下margin依然存在问题


   实例:(1)水平垂直居中

  如果要居中的元素的宽/高是不变的或者说是确定的,比如width/height=100px,那么设置absolute的top/left=50%,然后margin-left/margin-top=-50px即可

  如果要居中的元素的宽/高是不确定的,这时margin负值就不能使用具体的px了,可以使用百分比。但由于margin的百分比都是相对于包含块的宽度,所以这里限制了只能设置宽高相同的居中元素。包含块的宽度如何获得呢?利用absolute的包裹性,在需要居中的元素外面套一个空的<div>元素即可
     
        (2)列表项两端对齐

  比如外层元素宽度为200px,内层3个元素,宽度为60px,margin-right为10px。这里,正常流中块级元素框的水平总和总共为210px,超过了父元素的宽度200px,则第三个元素会被挤下来。当然可以给第三个元素设置margin-right=0。但,这种方法不优雅,为布局而布局,第三个元素并没有什么特殊的,却被设置了特殊的样式

  优雅的方法应该是内层元素和外层元素之间包一层元素,设置margin-right=-10px,使块级元素框的水平总和总共为210px - 10px = 200x ,等于父元素的宽度即可

  [注意]设置overflow:hidden用于清除浮动

33.

call()和 apply()都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,
    就是为了改变函数体内部 this 的指向。因为 JavaScript 的函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。
    call(),apply()二者的作用完全一样,只是接受参数的方式不太一样。
        例如,有一个函数 func1 定义如下:var func1 = function(arg1, arg2) {};
    就可以通过 func1.call(this, arg1, arg2); 或者 func1.apply(this, [arg1, arg2]); 来调用。
    其中 this 是你想指定的上下文,他可以任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,
    而 apply 则是把参数放在数组里。JavaScript 中,某个函数的参数数量是不固定的,

*****重要:因此要说适用条件的话,当你的【参数数量确定时】,用 call,而【参数数量不确定】的时候,用 apply,
    然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数


34.JS中创建对象的方式:
            1···工厂模式        
                fn(x1,x2,x3){
                    var o = new Object();
                    o.x1 = x1;
                    o.x2 = x2;
                    o.x3 = x3;
                    o.sayx1 = function(){                    
                        alert(this.name);
                    }
                }
                优缺点:可以创建多个相似对象,但无法解决对象识别问题

            2···构造函数模式
                fn(x1,x2,x3){
                    this.x1 = x1;
                    this.x2 = x2;
                    this.x3 = x3;
                    this.sayx1 = function(){                    
                        alert(this.name);
                    }
                }
                优缺点:可以创建多个相似对象,但无法解决对象识别问题
            3···原型模式
            4···组合使用构造函数模式和原型模式
            5···动态原型模式
            6···寄生构造函数模式
            7···稳妥构造函数模式


35.关于函数:
    1)匿名函数:JavaScript函数可以是匿名的。可以从函数声明中省略函数名。但是,函数必须存储在变量中。
        var fn = function(x,y){return x+y};

    2)闭包:内部函数可以访问所有外部函数的变量和参数。内部函数是函数内部某种private实现,
        并且不能从外部函数以外被调用。内部函数的使用生成了JavaScript闭包,
    
    3)立即执行函数表达式:
        (function(){
            函数体
        }());

    4)构造函数:(函数名首字母建议大写)好处是,能够通过预定义的属性和方法,创造尽可能多的对象。可以类比到其他语言中的类和对象
-----------------------------------------------------------------------
        function Gouzao(属性1,属性2,...){
            this.属性1 = 属性1;
            this.属性2 = 属性2;
            ...

            this.方法1 = function(){alert(this.属性1)};
            ...
        }
        创建对象:
        var 对象1 = new Gouzao(属性1,属性2,...);
        var 对象2 = new Gouzao(属性1,属性2,...);
***注:使用构造器创建对象时,一定记住不能少了new关键字,否则属性和方法会赋给window对象;
    这样写在Gouzao的两个对象中方法1和方法2是两个不同的Function对象的实例,但是它们完成同一件事;
    因此上述构造函数的变体:
------------------------------------------------------------------------
        function Gouzao(属性1,属性2,...){
            this.属性1 = 属性1;
            this.属性2 = 属性2;
            this.方法1 = 方法1;//重要代码:此处将构造的属性和外部全局函数的引用联系起来;
            ...

        }
        function 方法1(){alert(this.属性1)};
            ...
        var 对象1 = new Gouzao(属性1,属性2,...);
        var 对象2 = new Gouzao(属性1,属性2,...);
    这样两个实例对象就共享了在全局作用域中定义的同一个方法1,问题是如果需要定义很多方法,则要定义很多全局函数,
    这样一来也失去了自定义引用类型的封装性.所以需要引入原型模式;

    5)原型:每一个函数都有prototype属性(prototype属性是一个指向原型对象的指针,原型对象在定义函数的同时被创建);
            eg:
                function demo(){

                    prototype;(prototype指向demo函数的原型对象demoprototype,默认只有一个constructor属性[包含指向demo函数的引用])
                }
    可以理解为demo函数的原型demo.prototype默认只包含一个constructor的属性,这个属性指向demo函数本身

***注意:只有函数对象才有prototype属性,因为每个对象都有一个隐藏的属性——“proto”,
    这个属性指向它的构造函数的prototype。即:fn.proto === Fn.prototype,这里的"proto"成为“隐式原型".

    超对象Object:Object.prototype 的proto指向 null;
    Object.__proto__ === Funtion.prototype;(true) 
    Function.__proto__ === Function.prototype;(true)
    Function.__proto__ ===    Object.__proto__;(true)
    Function.__proto__ === Function.prototype === Object.__proto__;(false)

    每个对象都有一个proto属性,指向创建该对象的函数的prototype
    obj.__proto__ === Object.prototype;
    Object.__proto__ === Function.prototype

    超构造函数Function.proto指向Function.prototype构成原型链中的循环接点(Function是超构造也是一个对象,所以有proto属性)
        上述说法的解释:所以Function是被自身创建的。所以它的proto指向了自身的prototype

    6)对象和函数的关系:    所有对象都是函数创建的--->用直接量创建对象的方法其实本质是省略了先实例化后赋值,函数是对象,也是属性的集合;
        var obj = {a:1,b:"str"};这种写法只是简写(语法糖),而本质是:var obj = new Object; obj.a = 1;obj.b = "str";    

    7)基本类型的值类型判断方法为:typeof
    引用类型的值类型的判断方法为instanceof
        A instanceof B;
        Instanceof的判断队则是:沿着A的proto这条线来找,同时沿着B的prototype这条线来找,
        如果两条线能找到同一个引用,即同一个对象,那么就返回true。如果找到终点还未重合,则返回false
        Object instanceof Function;//true
        Function instanceof Object;//true
        Function instanceof Object;//true


    8)原型链:访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着proto这条链向上找,这就是原型链;
        foo.__proto__ === Foo.prototype;
****注意:对象的原型链是沿着proto这条线走的,因此在查找f1.hasOwnProperty属性时,
    就会顺着原型链一直查找到Object.prototype。Object.prototype挂载在Object函数对象下

****注意:在js对象中属性就相当于对象中的索引;for...in循环(用来遍历)输出的是数组的索引和对象的属性名

        

    9)继承:
        [对象]由于所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。
        这就是所谓的“继承”。

        [函数]每个函数都有call,apply方法,都有length,arguments,caller等属性。为什么每个函数都有?
        这肯定是“继承”的。函数由Function函数创建,因此继承的Function.prototype中的方法;
        hasOwnProperty()方法是Function.prototype继承自Object.prototype的方法
        Function.prototype.__proto__  === Object.prototype;

    总结:函数的原型对象的constructor属性默认指向函数本身,原型对象除了有原型属性外,为了实现继承还有原型链指针
        __proto__,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用__proto__一直
        指向Object的原型对象上,而Object的原型对象用Object.prototype.__proto__ = null表示原型链的最顶端
        ,如此变成了Js的原型链继承,也解释了所有的js对象都具有Object的基本方法;

tips(总结):    1. 首先Object和Function都是构造函数,而所有的构造函数的都是Function的实例对象. 
            因此Object是Function的实例对象
        2. Function.prototype是Object的实例对象
        3. 实例对象的原型(以__proto__来表示)会指向其构造函数的prototype属性, 
           因此  Object.__proto__ === Function.prototype,
             Function.__proto__ === Function.prototype, (自己互为构造和实例)
               Function.prototype.__proto__ === Object.prototype,
             Object.__proto__.__proto__ === Object.prototype,
             Object.prototype.__proto__ === null;(原型链的头部,jsBase对象没有原型)
        4. 当我们访问一个属性值的时候, 它会沿着原型链向上查找, 直到找到或者到Object.prototype.__proto__(为null)截止.

        5.Object.prototype(或Function.prototype)只是挂载(留了空位,还没坐,但是占了座)在Object(或Function)函数对象上的,并没有值
        
        6.__proto__(隐式原型)和prototype(显式原型):访问对象的属性首先查找本地,没有就去它的__proto__属性里找...依次这样沿着原型链往
            上寻找...
            每一个函数对象都自带prototype属性,它指向函数的原型对象
        7.__proto__是对象实例访问原型对象,prototype是构造函数访问原型对象
        8.prototype属性是一个指向原型对象的指针,原型对象在定义函数的同时被创建。
          __proto__是js每个对象默认包含的属性,它指向构造函数的原型对象;
          所以才有:构造.prototype === 实例.__proto__ (共用同一个指向原型对象的引用);


36.js的执行上下文(环境):
    “函数表达式”:var f1 = function(){};
    “函数声明”:  function f2(){};
    js中代码执行包括准备(编译)阶段和运行(执行)阶段

    *)在准备阶段js做的工作有:
        变量、函数表达式——变量声明,默认赋值为undefined;
        this——赋值;
        函数声明——赋值;
    这些工作就在准备阶段生成了执行上下文,函数每调用一次就会产生不同的执行环境,多次调用就会
    产生多个执行上下文,那么这些上下文如何管理,内存怎么释放则要交给--执行上下文栈--;
----------------------------------------------------------------------------------------------------------------------

37.this的指向(js最重要的概念之一):
    this在建立运行上下文的时候就被赋值,因此关于this的取值,是非常关键的概念
    1)构造函数中this在实例化的时候指向实例对象
        function Foo(){
            this.属性;
            this.方法;//code
        }
        var foo = new Foo();

        在code中的this指向foo(对象实例)
    (***千万注意:当Foo被直接调用,而没有new对象的时候,this是指window***)

    2)函数作为对象的属性(方法)并被调用,this指向调用函数的对象:
        var obj  = {
            x : 10,
            fn : function(){
                console.log(this);//{x:10,fn:f}
                console.log(this.x);//10
            }
        };
        
        obj.fn();

    以上代码中,fn不仅作为对象obj的属性,而且作为属性被obj调用,因此this就是调用方法的对象obj

    3)函数作为对象的属性(方法)但未被该对象调用,this指向全局(this其实就是当前执行环境)
        var obj = {
            x:10,
            fn:function(){
                console.log(this);//window
                console.log(this.x);//undefined
        }
        
        var fn1 = obj.fn;
        fn1();
    //以上代码中,fn函数的引用赋给另一个变量,没有作为对象的方法被调用,则this是window,this.x就是undefined

    4)函数用call()或者apply()来调用时,this的值就取传入的对象的值(因为call(),apply()其实就是改变this的指向).
        var obj = {
            x:10;
        };
        
        var fn  = function(){
            console.log(this);//obj{x:10}
            console.log(this.x);//10
        };
    
        fn.call(obj);

    5)全局调用普通函数
        console.log(this===window);//true
        全局环境下,this永远是window。

        普通函数调用时,其中this也是window

    1********
        var x = 10;

        var fn = function(){
            console.log(this);//Window
            console.log(this.x);//10
        };

        fn();
        
(易错易错)2*******只要函数不是作为对象属性切被对象直接调用,不管其在不在obj内部,函数体内部this也指向Window
    var obj = {
        x:10;
        fn:function(){
        function f(){
            console.log(this);//Window
            console.log(this.x);//undefined
        }
            f();
        }
    };
        obj.fn();
----------------------------------------------------------------------------------------------------------------------

38.window(浏览器窗口对象)和Window(浏览器窗口对象构造器)
    
    typeof window;//function
    typeof Window;//object
    window.constructor===Window;//true
    window.instanceof Window;//true----------------------(instanceof运算符用来判断一个构造函数的prototype
                    属性所指向的对象是否存在另外一个要检测对象的原型链上
                    即等价于:window.__proto__===Window.prototype)

    说明window是Window的实例,Window是window对象的构造函数

39.执行上下文栈:    
    执行全局代码时,会产生一个执行上下文环境,每次调用函数都又会产生执行上下文环境。
    当函数调用完成时,这个上下文环境以及其中的数据都会被···消除···,再重新回到全局上下文环境。
    处于活动状态的执行上下文环境只有一个。
    
    其实这是一个压栈出栈的过程——执行上下文栈

40.作用域和上下文环境

    一个作用域下可能包含若干个上下文环境。有可能从来没有过上下文环境(函数从来就没有被调用过);
    有可能有过,现在函数被调用完毕后,上下文环境被销毁了;有可能同时存在一个或多个(闭包)。

    1) 上下文环境:

    可以理解为一个看不见摸不着的对象(有若干个属性),虽然看不见摸不着,但确实实实在在存在的,
    因为所有的变量都在里面存储着,要不然咱们定义的变量在哪里存?
    另外,对于函数来说,上下文环境是在调用时创建的,这个很好理解。
    拿参数做例子,你不调用函数,我哪儿知道你要给我传什么参数?

    2) 作用域:

    首先,它很抽象。第二,记住一句话:除了全局作用域,只有函数才能创建作用域。
    创建一个函数就创建了一个作用域,无论你调用不调用,函数只要创建了,它就有独立的作用域,
    就有自己的一个“地盘”。

41.自由变量:

    var x =  10;
    function obj(){
        console.log(x);
    }
    对于obj的作用域来说,x没有在obj中声明,因此对obj作用域来说,x就是自由变量;

42.作用域链;
    
    自由变量的取值是在···创建···(而不是调用)这个对应作用域的函数中去取的,这个作用域(类似上述obj的作用域)也叫"静态作用域"。
    先跨一步去找,如果没有找到就接着跨域直到找到自由变量的值为止,否则一直找到全局作用域。
    
    这个根据自由变量所在函数对应的静态作用域的跨域路线称为作用域链;


43.闭包:

    引入两个概念:
    1)函数作为返回值:
    eg:

        function fn(){
            var max = 10;
            return function obj(x){
                if(x>max){
                    console.log(x);
                    }
                };
            }
        var f1 =  fn();
        max = 100;
        f1(15);//此时如果写成fn(15)则打印出的是obj函数体,而不是15;

        //15
    ···上述代码中,obj函数作为返回值,赋值给f1变量.执行f1(15)时,用到了fn作用域下的max变量的值,
    这个跨域取值的原理就是上一点中作用域链的跨域原理(以自由变量所在函数的静态作用域为单位跨域)
    
    2)函数作为参数被传递:

    eg: 
        var max =  10,
        fn = function(x){
            if(x>max){
                console.log(x);
            }
        };
    
        (function (f) {
            var max =  100;
            f(15);
        })(fn);
        
    ···上述代码中,fn函数作为一个参数被传递到另一个函数,赋值给f形参。执行f(15)时,max取值为10,
        而不是100.这个取值还是上述自由变量跨域取值的原理;

    
    
    讲述:例如第一种情况,分析代码执行情况
eg:

    1    function fn(){
    2        var max = 10;
    3        return function obj(x){
    4            if(x>max){
    5                console.log(x);
    6                }
    7            };
    8        }
    9    var f1 =  fn();
    10    max = 100;
    11    f1(15);

1·代码执行前,先生成全局上下文执行环境,并在执行时对其中的变量进行赋值。此时全局上下文环境是活动状态。
            
                {    max=undefined
    全局上下文执行环境    {
                {    ...其他    

2·执行全局代码第9行,调用fn,产生fn()执行上下文环境,设为活动状态,压栈
            
                {    max=undefined
    全局上下文执行环境    {
                {    ...其他    

    和
    
                {    max=10
    fn上下文执行环境    {
                {    ...其他    
    
3·执行完第9行,fn()调用完成。按理说应该销毁掉fn()的执行上下文环境,但是这里不能这么做,因为fn执行时返回的是一个函数。
    函数的特别之处在于可以创建一个独立的作用域。而正巧合的是,返回的这个函数体中,
    还有一个自由变量max要引用fn作用域下的fn()上下文环境中的max。因此,这个max不能被销毁,
    销毁了之后bar函数中的max就找不到值了。    执行到第10行,max = 100,则此时上下文栈中活动上下文为:

                {    max=100
    全局上下文执行环境    {
                {    ...其他    

    和
    
                {    max=10
    fn上下文执行环境    {
                {    ...其他    
    
4·执行到第11行,执行f1,即执行obj(),产生obj执行上下文环境,设为活动状态,压栈

                {    max=100
    全局上下文执行环境    {
                {    ...其他    

    和
    
                {    max=10
    fn上下文执行环境    {
                {    ...其他    

    和

                {    x=15
    obj上下文执行环境    {
                {    ...其他    

执行obj时,会去fn的执行上下文中寻找自由变量max的值,让fn的执行上下文环境在调用完后依然保留,这就是闭包产生的影响,
内存得不到释放.


44.递归函数调用;
    eg:阶乘函数
        function factorial(num){                    var factorial =( function f(num){
            if(num<=1){                            if(num<=1){
            return 1;                规范写法:        return 1;
            }else{                                }else{
            return num * factorial(num-1);                    return num * f(num-1);
        }                                }

    }                                });
                                            
                        
···上述第一种写法会在下面代码执行后报错;
    var fac_another =  factorial;
    factorial = null;
    alert(fac_another(4));//报错
因为将函数引用传给另一个变量后,将null传给原函数名,函数体内的函数名则值为null,因此推荐第二种写法(创建一个名为f()的函数命名表达式)

45.JSON:
    1)JSON.stringify():    javaScript对象    A------->JSON字符串    B

    2)JSON.parse():        JSON字符串    B----------->javaScript对象    A1(这个对象和原来A对象属性一致,但是两个独立的对象)
 

转载于:https://my.oschina.net/u/3788198/blog/1818571

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值