web前端开发必懂之一:JS继承和继承基础总结

  首先,推荐一篇博客豪情的博客JS提高篇: http://www.cnblogs.com/jikey/p/3604459.html ,里面的链接全是精华, 一般人我不告诉他;

  我们会先从JS的基本的设计模式开始,由浅入深:

  工厂模式:因为使用用一个接口创建很多对象会产生大量的重复代码,为了解决这个问题,人们就开始使用工厂模式:

  

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        //工厂模式:因为使用用一个接口创建很多对象会产生大量的重复代码,为了解决这个问题,人们就开始使用工厂模式:
        function Person(hairs,face, eye) {
            var o = new Object();
            o.hairs = hairs;
            o.face = face;
            o.eye = eye;
            o.say = function(){
                console.log("say someting to me!");
            };
            return o;
        };
        //我们通过 Person(0,1,2)就可以创建一个包含特定信息的Person对象, 以后要生成对象直接执行Person然后给他传参数就好了;
        //比如我们要生成10个Person, 很方便很快;
        var c = 10;
        while( c-- ) {
            console.log(Person(c,c,c))
        };
    </script>
</body>
</html>

  



  构造函数模式:使用构造函数模式我们能少些更多代码,比如上面的工厂模式我们可以改写成:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        function Person(hairs, face, eye) {
            this.hairs = hairs;
            this.face = face;
            this.eye = eye;
        };
        //同样, 我们再生成10个小朋友
        var c = 10;
        while( c-- ) {
            console.log( new Person(c,c,c) );
        };

    </script>
</body>
</html>

  //知识点1: 那么工厂模式和构造函数模式有什么区别呢:

  /*
  * 没有显式地创建对象
  * 直接把属性和方法赋值给了this
  * 没有return语句
  * 构造函数的前面有一个new;
  * */

  // 知识点2:

  /*
  * 通过new的构造函数会经过四个阶段:
  * 1:创建一个新对象;
  * 2:把this赋值给这个新对象
  * 3:执行构造函数中的代码
  * 4:返回新对象
  * */



  原型是神马? 原型就是公用的方法或者属性,这么理解最简单, 当然:

      1、prototype本质上还是一个JavaScript对象;

   2、每个函数都有一个默认的prototype属性;

  3、通过prototype我们可以扩展Javascript的内建对象

  一些代码弄懂原型的本质:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        function Memo() {};
        Memo.prototype.hehe = 1;
        Memo.prototype.shut = function() {
            console.log("miaomiao")
        };
        var m0 = new Memo();
        var m1 = new Memo();
        console.log(m0.shut === m1.shut); //ture, 因为m0的shut和m1的shut就是指向了Memo.prototype.shut这个方法,所以他们相等;
        //Object.getPrototypeOf会返回实例的原型;
        console.log(Object.getPrototypeOf(m0)) //输出了:Memo {hehe: 1, shut: function}
        console.log( Memo.prototype.isPrototypeOf(m0) )// 输出: true;

        //原型对象有一个很大的问题要非常注意 ==》》 原型的属性和方法是被共享的, 比如:
        Memo.prototype.shut = "W_W";
        l(m0.shut) //输出:W_W, 悲剧了吧, 本来原型上的shut是个方法, 被改成字符串以后, 实例上的shut也发生了改变;
        l(m1.shut) //输出:W_W;

        m0.__proto__.shut = 1111; //m0的__proto__指向了Memo.prototype.shut,__proto__在标准浏览器下面是不能枚举到的,但确实是存在的一个属性;
        l(m1.shut) //输出了1111
        //只要原型上的属性或者方法被改了, 实例上的也会发生改变;
    </script>

</body>

</html>

  知识点:Object.getPrototypeOf;

      Fn.prototype.isPrototypeOf( instance );



  好的, 现在再来了解一下constructor, 如果你已经知道constructor是什么的话,  这段略过, constructor是默认指向创建当前对象的构造函数, 但是这里面有一些坑要注意, 比如你的原型prototype被改了, 实例的constructor就变了 ,

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        var Fn = function(){
            //我是构造函数Fn;
        };
        l("Fn的constructor");
        l(Fn.prototype.constructor);
        /*输出function (){
         //我是构造函数Fn;
         } */

        var f = new Fn;
        l("f的constructor");
        l(f.constructor);
        /*输出;
         * function (){
         //我是构造函数Fn;
         }*/
        //当函数创建的时候默认就为prototype新建一个constructor指向自己;

        l(Fn.constructor === Function); //输出true, Function这个构造函数是Function;
        l(Fn.constructor) // 输出function Function() { [native code] } ,意思是Function这个构造函数 ;
        l(Fn.constructor === Fn.__proto__.constructor) //输出true; Fn的constructor实际上是指向Fn.__proto__的;

        //好的, 现在重新定义一个Fn;
        var Fn = function(){
            //我是构造函数Fn;
        };
        Fn.prototype = {};
        l(Fn.prototype.constructor)
        /*打印出了内部的代码, 为什么呢? 因为我们改变了Fn的原型, Fn的constructor指向了{}空对象的Contructor;
         * function Object() { [native code] }  */
    </script>
</body>
</html>


  大家一定要懂的是实例上的__proto__就是指向原型上的prototype, 这样会少走一些弯路,可以节约更多的时间用来看片, 你懂的;
  每一个函数新建的时候都有一个默认的prototype,  prototype这个对象上面默认有一个指向自己的constructor;
  prototype和__proto__的区别:__proto__是实例和Person.prototype之间的关系,而constructor是实例和Person之间的关系

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        var Fn = function() {};
        Fn.prototype.hehe = 1;
        Fn.prototype.lala = 2;
        var f = new Fn;
        l(f) //输出了Fn {hehe: 1, lala: 2} ;
        l(f.__proto__) //输出了Fn {hehe: 1, lala: 2} ;
        l(Fn.prototype === f.__proto__) //输出了true, 这里要懂的东西是实例上的__proto__这个属性指向了构造函数的prototype;
        l(f === f.__proto__) //输出false; 这里要懂的是f是new出来的实例;

        //因为f上面的hehe和lala都是继承的属性, 所以这里面的log并没有被输出;
        for(var p in f){
            l("输出所以属性:" + p); //输出所以属性:hehe demo.html:11;   输出所以属性:lala
            //过滤非私有属性;
            if( f.hasOwnProperty(p) )
                l("输出私有属性" + p); //因为f没有私有属性,所以这边没有log出来;
        };
    </script>
</body>
</html>

  



  有了上面的基础, 我们开始说说JS的面向对象和继承吧;
  

  1:组合使用构造器和原型模式, 这种模式是构造函数和原型混合的模式, 使用最广泛, 认同度也最高的一种模式, 也是最基础的模式;

  

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        function Duck( name ,word) {
            this.name = name;
            this.word = word;
        };
        Duck.prototype.say = function() {
            console.log( this.name+" say : " + this.word )
        };
        var duck = new Duck("nono","hehe");
        duck.say();
    </script>
</body>
</html>

 

   寄生构造模式; 听名字真的很玄乎..其实跟工厂模式一模一样的, 其实就是自定义的模型封装;

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        function Foxy(name , word) {
            var result = new Object();
            result.name = name;
            result.word = word;
            return result;
        };
        l( new Foxy("nono","say someting") ); //输出:Object {name: "nono", word: "say someting"} ;
        function Monkey( ) {
            var aResult = [];
            //技巧:通过apply把arguments保存到数组;
            aResult.push.apply(aResult, arguments);
            return aResult;
        };
        l( new Monkey("nono","dino","kite","sam") );  //打印出了这个:["nono", "dino", "kite", "sam"];
        //要注意的是使用寄生模式的返回的对象和构造函数一点关系都没有;
    </script>
</body>
</html>


  JS的原型继承, 继承是依赖于原型链的;那么JS原型链是什么呢:
  /* 这段话慢慢读, 从搞基3抄的,很重要, 最好自己看一看哇;
  * ECMAScript中描述了原型链的概念, 并将原型链作为实现继承的主要方法, 基本思想是利用引用类型继承另一个引用类型的属性和方法。
  * 简单回顾一下构造函数,原型和实例的关系:每一个函数都有一个原型对象, 每一个原型对象都有一个指向构造函数的指针,
  * 而实例包含了一个指向原型对象的内部(不可见的)指针。 那么我们让原型对象等于另一个类型的实例, 那么这个原型对象将会包含指向
  * 另一个原型对象的指针,如果另一个原型对象又是指向了别的原型的一个实例, 这样层层嵌套, 就形成了原型链;
  * */
  那么我们利用原型的原型链相互继承来写一个基本的例子:  

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        var Fn = function() {
            this.property = true;
        }
        Fn.prototype.getFnProperty = function() {
            console.log( this.property );
        };
        var SubFn = function() {
            this.subProperty = false;
        };
        //SubFn继承了Fn的实例
        SubFn.prototype = new Fn();
        //为实例添加额外的实例方法;
        SubFn.prototype.getSubProperty = function(){
            console.log(this.subProperty);
        };
        var subFn = new SubFn();
        subFn.getFnProperty(); //输出了true
        subFn.getSubProperty(); //输出了false
        /*现在subFn的constructor 是
         function () {
         this.property = true;
         };
         所以要修正SubFn.prototype.constructor = SubFn
         */
    </script>
</body>
</html>

  原型式继承第二个例子:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        // 首先, 准备一个方法;
        var inherit = function(o) {
            if(!typeof o === "object")return;
            function F () {}
            F.prototype = o;
            F.prototype.constructor = F;
            return new F();
        };

        var Fn = function() {
            this.property = true;
        }
        Fn.prototype.getFnProperty = function() {
            console.log( this.property );
        };
        var SubFn = function() {
            this.subProperty = false;
        };
        //SubFn继承了Fn的实例
        SubFn.prototype = new Fn();
        //为实例添加额外的实例方法;
        SubFn.prototype.getSubProperty = function(){
            console.log(this.subProperty);
        };
        var subFn = new SubFn();

        //这个方法的内部, 临时创建了一个构造函数, 然后将传入的对象作为这个构造函数的原型, 最后返回一个临时的新实例;
        //ECMASscript 5 有新增了一个Object.create 效果和inherit一模一样, 它可以接收第二个参数,
        // 第二个参数要通过defineProperties的方式设置,会覆盖原型的属性, 比如:
        Object.create(subFn, {
            getFnProperty: {
                value:1
            }
        });
        var Fn = function() {};
        //如果我们inherit传对象;
        Fn.prototype = inherit( {0:0,1:1,2:2,3:3,4:4} );
        l( new Fn ) //==>Fn {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, constructor: function(){....} 继承了哦
        //如果我们给inherit传一个构造函数的实例;
        Fn.prototype = inherit( new SubFn );
        l(new Fn);
    </script>
</body>
</html>

  有时候看到原型的各种引用会尿失禁, 引用来引用去的,坑爹啊, 不说了去洗裤子了....

  

  

  寄生组合式继承  

  组合继承是JS的常用继承模式, 但是也有自己的不足, 组合继承最大的问题的无论是什么情况下, 都会两次调用超类的构造函数;
  一个是在创建子类原型的时候, 另一个是在子类构造函数的内部,  那么子类的原型会包含所有超类实例的全部属性
  寄生组合式继承就是为了解决子类原型包含所有超类实例全部属性这个问题而存在的;
  

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        //最好所有的代码自己打一遍, 增加印象;
        function l ( arg ) {
            console.log( arg );
        };
    </script>

    <script>
        var inherit = function(o) {
            if(!typeof o === "object")return;
            function F () {}
            F.prototype = o;
            F.prototype.constructor = F;
            return new F();
        };
        //首先要准备inheritPrototype方法;
        var util = util || {};
        util.inherit = inherit;
        util.inheritPrototype = function(subType, superType) {
            var _prototype = this.inherit( superType.prototype );
            _prototype.constructor = subType;
            subType.prototype = _prototype;
        };
        function F( name ) {
            this.name = name;
            this.type = "human";
            this.habits = ["dance","code"];
        };
        F.prototype.laugh = function() {
            console.log("heha!");
        };
        var InheritF = function() {
            F.apply( this, arguments );
        };
        util.inheritPrototype(InheritF, F);
        InheritF.prototype.letsGo = function() {
            l("1,2,3,4")
        };
        var nono = new InheritF("nono");
        nono.habits.push("read books");
        l(nono.habits)
        var nonono = new InheritF("nono");
        l( nonono.habits );
        //继承的方法千万种,万变不离其宗;
    </script>
</body>
</html>

  JS各种继承的库推荐, 可以加深印象:

  首先是:

    JS.Class 是一个mootools式的类工厂 基于 lunereaper<![[dawid.kraczkowski[at]gmail[dot]com]]>的项目进行修改, 让子类的实现更简洁;

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        JS = {};
        // 这个是库的源代码;
        JS.Class = function(classDefinition) {

            //返回目标类的真正构造器
            function getClassBase() {
                return function() {
                    //它在里面执行用户传入的构造器construct
                    //preventJSBaseConstructorCall是为了防止在createClassDefinition辅助方法中执行父类的construct
                    if (typeof this[‘construct‘] === ‘function‘ && preventJSBaseConstructorCall === false) {
                        this.construct.apply(this, arguments);
                    }
                };
            }
            //为目标类添加类成员与原型成员
            function createClassDefinition(classDefinition) {
                //此对象用于保存父类的同名方法
                var parent = this.prototype["parent"] || (this.prototype["parent"] = {});
                for (var prop in classDefinition) {
                    if (prop === ‘statics‘) {
                        for (var sprop in classDefinition.statics) {
                            this[sprop] = classDefinition.statics[sprop];
                        }
                    } else {
                        //为目标类添加原型成员,如果是函数,那么检测它还没有同名的超类方法,如果有
                        if (typeof this.prototype[prop] === ‘function‘) {
                            var parentMethod = this.prototype[prop];
                            parent[prop] = parentMethod;
                        }
                        this.prototype[prop] = classDefinition[prop];
                    }
                }
            }

            //其实就是这样的Base = function() {};别想太多了;
            var preventJSBaseConstructorCall = true;
            var Base = getClassBase();
            preventJSBaseConstructorCall = false;

            createClassDefinition.call(Base, classDefinition);

            //用于创建当前类的子类
            Base.extend = function(classDefinition) {

                //其实就是这样的Base = function() {};别想太多了;
                preventJSBaseConstructorCall = true;
                var SonClass = getClassBase();
                SonClass.prototype = new this();//将一个父类的实例当作子类的原型
                preventJSBaseConstructorCall = false;

                createClassDefinition.call(SonClass, classDefinition);
                SonClass.extend = this.extend;

                return SonClass;
            };
            return Base;
        };
    </script>
    <script>
        //这是实际案例;
        var Animal = JS.Class({
            construct: function(name) {
                this.name = name;
            },
            shout: function(s) {
                console.log(s);
            }
        });
        var animal = new Animal();
        animal.shout(‘animal‘); // animal

        var Dog = Animal.extend({
            construct: function(name, age) {
                //调用父类构造器
                this.parent.construct.apply(this, arguments);
                this.age = age;
            },
            run: function(s) {
                console.log(s);
            }
        });
        var dog = new Dog("dog", 4);
        console.log(dog.name);
        dog.shout("dog"); // dog
        dog.run("run"); // run
        console.log(dog.constructor + "")
        var Shepherd = Dog.extend({
            statics: {//静态成员
                TYPE: "Shepherd"
            },
            run: function() {//方法链,调用超类同名方法
                this.parent.run.call(this, "fast");
            }
        });
        console.log(Shepherd.TYPE);//Shepherd
        var shepherd = new Shepherd("shepherd", 5);
        shepherd.run();//fast
        var a = new Animal("xx");
        console.log(a.run);
    </script>
    </body>
</html>

  这款继承创建的作者是jQ的作者,你懂的, 不饶;

  https://github.com/html5crew/simple-inheritance

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
    <script>
        /* source: https://gist.github.com/shakyShane/5944153
         *
         * Simple JavaScript Inheritance for ES 5.1 ( includes polyfill for IE < 9 )
         * based on http://ejohn.org/blog/simple-javascript-inheritance/
         *  (inspired by base2 and Prototype)
         * MIT Licensed.
         */
        (function (global) {
            "use strict";

            if (!Object.create) {
                Object.create = (function () {
                    function F() {
                    }

                    return function (o) {
                        if (arguments.length !== 1) {
                            throw new Error("Object.create implementation only accepts one parameter.");
                        }
                        F.prototype = o;
                        return new F();
                    };
                })();
            }

            var fnTest = /xyz/.test(function () {
                /* jshint ignore:start */
                xyz;
                /* jshint ignore:end */
            }) ? /\b_super\b/ : /.*/;

            // The base Class implementation (does nothing)
            function BaseClass() {
            }

            // Create a new Class that inherits from this class
            BaseClass.extend = function (props) {
                var _super = this.prototype;

                // Instantiate a base class (but only create the instance,
                // don‘t run the init constructor)
                var proto = Object.create(_super);

                // Copy the properties over onto the new prototype
                for (var name in props) {
                    // Check if we‘re overwriting an existing function
                    proto[name] = typeof props[name] === "function" &&
                            typeof _super[name] === "function" && fnTest.test(props[name]) ?
                            (function (name, fn) {
                                return function () {
                                    var tmp = this._super;

                                    // Add a new ._super() method that is the same method
                                    // but on the super-class
                                    this._super = _super[name];

                                    // The method only need to be bound temporarily, so we
                                    // remove it when we‘re done executing
                                    var ret = fn.apply(this, arguments);
                                    this._super = tmp;

                                    return ret;
                                };
                            })(name, props[name]) :
                            props[name];
                }

                // The new constructor
                var newClass = function () {
                    if (typeof this.init === "function") {
                        this.init.apply(this, arguments);
                    }
                };

                // Populate our constructed prototype object
                newClass.prototype = proto;

                // Enforce the constructor to be what we expect
                proto.constructor = newClass;

                // And make this class extendable
                newClass.extend = BaseClass.extend;

                return newClass;
            };

            // export
            global.Class = BaseClass;
        })(this);
    </script>
    <script>
        var Fn = function() {};
        //对继承的插件进行引用;
        Fn.extend = window.Class.extend;
        Fn.prototype.lala = 1;
        Fn.prototype.say = function() {
            alert( this.lala );
        };
        var Foo = Fn.extend({
            dudu:2,
            init:function(){
                this.name="nono"
            },
            dayDudu:function(){
                alert(this.dudu);
            }
        })
    </script>
    </body>
</html>

  执行 new Foo打印出来对象结构如下:

  吃饭去了, 爽歪歪;

  

  最后提供一些参考的链接:

    javascript 类属性、类方法、类实例、实例属性、实例方法、prototype、__proto__ 测试与小结: 

      http://www.cnblogs.com/mrsunny/archive/2011/05/09/2041185.html

    JS的构造函数:

      http://www.cnblogs.com/jikey/archive/2011/05/13/2045005.html

    浅析Javascript原型继承:

      http://blog.csdn.net/kittyjie/article/details/4380918

end

时间: 2024-08-25 09:33:22

web前端开发必懂之一:JS继承和继承基础总结的相关文章

前端开发必须知道的JS之闭包及应用

本文讲的是函数闭包,不涉及对象闭包(如用with实现).如果你觉得我说的有偏差,欢迎拍砖,欢迎指教. 在前端开发必须知道的JS之原型和继承一文中说过下面写篇闭包,加之最近越来越发现需要加强我的闭包应用能力,所以此文不能再拖了.本文讲的是函数闭包,不涉及对象闭包(如用with实现).如果你觉得我说的有偏差,欢迎拍砖,欢迎指教. 一. 闭包的理论 首先必须了解以下几个概念: 执行环境 每调用一个函数时(执行函数时),系统会为该函数创建一个封闭的局部的运行环境,即该函数的执行环境.函数总是在自己的执行

web前端开发必看的14本书!

第一阶段:HTML和CSS的学习 HTML就不多说了,基础中的基础,这个都不会的小伙伴请参见HTML手册,认真学习W3C课程,稍有基础之后可以跟着视频学习<HTML+CSS基础课程>. 欧克!荐书开始! 1.<CSS权威指南>第三版 这本书实在太适合小白用户了,是一本为初学者清扫障碍的书籍.同行一致认为这本书是学习CSS基础的首选.CSS界权威Meyer大师的作品,翻译水平也灰常赞! 2.<CSS那些事儿> 住邦2000写字楼出租众合鑫房产 热门商圈楼盘出租,设施齐全,

WEB前端开发 必会的二十五个知识点

1. 常用那几种浏览器测试?有哪些内核(Layout Engine)?(Q1) 浏览器:IE,Chrome,FireFox,Safari,Opera.(Q2) 内核:Trident,Gecko,Presto,Webkit. 2. 说下行内元素和块级元素的区别?行内块元素的兼容性使用?(IE8 以下)(Q1) 行内元素:会在水平方向排列,不能包含块级元素,设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效. 块级元素:各占据一行,垂

web前端开发分享-css,js工具篇

来源:http://www.cnblogs.com/jikey/p/3607133.html web前端开发乃及其它的相关开发,推荐sublime text, webstorm(jetbrains公司系列产品)这两个的原因在于,有个技术叫emmet, http://docs.emmet.io,而这两个对他的支持是: sublime text 是所有编辑器里边支持emmet比较好的的唯一一款. webstorm是所有编辑器里边唯一内置emmet的一款,并且将emmet的精神往前推动的一款. php

web前端开发初学者必看的学习路线图课程内容分享

随着web前端需求量的日益增加,企业对前端人员的技能要求也越来越高,我们如何能学到满足企业的web前端技能,向着高薪前进,那你就的了解企业需要的人才需求,还的提升自身的技术能力,那么想从事web前端行业,web前端开发主要学什么课程呢? 前端是一门衔接UI和后台开发的职位,web前端工程师课程要完全覆盖这些较新的技术内容,才能紧跟技术步伐.那么的web前端课程都学什么呢? 第一阶段:前端页面重构 内容包含了:(PC端网站布局项目.HTML5+CSS3基础项目.WebApp页面布局项目) 第二阶段

Web前端开发十日谈

一直想写这篇“十日谈”,聊聊我对Web前端开发的体会,顺便解答下周围不少人的困惑和迷惘.我不打算聊太多技术,我想,通过技术的历练,得到的反思应当更重要. 我一直认为自己是“初级”前端开发工程师,一方面我入道尚浅,只有短短几年,另一方面我自知对技术的钻研并不深入,可能是由于环境的原因,当然最重要的是,我幸运的参与到互联网崛起的浪潮之巅.时势造就了一批技能薄弱但备受追捧的“弄潮者”,这在很大程度上影响我们对“技术本质”的洞察力,多年来也一直未有成体系的“前端技术”布道佳作,以至于当下多数人对前端技术

编写高质量代码:Web前端开发修炼之道(一)

最近老大给我们买来一些技术方面的书籍,其实很少搬着一本书好好的完整的看完过,每每看电子档的,也是打游击式的看看这章,瞅瞅那章,在那5本书中挑了一本比较单薄的<编写高质量代码web前端开发修炼之道>,看完觉得不错,它从一个整体架构上来说明如何编写高质量代码,而细处也着重说明一些比较重要的技术点,给人一种从高处俯瞰web开发.很完整的感觉,在这感谢老大,谢谢他让我们不停的进步着.下面是我看书过程中的笔记. 第一章:从网站重构说起 没什么好说的,从一个糟糕的老网页实例说明需要将web的结构,样式和行

淘宝前端工程师:国内WEB前端开发十日谈

转自:http://www.jianshu.com/p/8cf2df3fdbf2 一直想写这篇“十日谈”,聊聊我对Web前端开发的体会,顺便解答下周围不少人的困惑和迷惘.我不打算聊太多技术,我想,通过技术的历练,得到的反思应当更重要. 我一直认为自己是“初级”前端开发工程师,一方面我入道尚浅,只有短短几年,另一方面我自知对技术的钻研并不深入,可能是由于环境的原因,当然最重要的是,我幸运的参与到互联网崛起的浪潮之巅.时势造就了一批技能薄弱但备受追捧的“弄潮者”,这在很大程度上影响我们对“技术本质”

《编写高质量代码--Web前端开发修炼之道》读书笔记

前言 这两周参加公司的新项目,采用封闭式开发(项目成员在会议室里开发),晚上加班到很晚,所以没时间和精力写原创博客了,今天就分享下这篇<编写高质量代码--Web前端开发修炼之道>读书笔记吧. 正文 欲精一行,必先通十行. 在前端开发这个领域,一专多能更是非常必要的. table布局缺点: 代码量大,结构混乱: 标签语义不明确,对搜索引擎不友好. css布局:div+css,或者(x)html+css. 代码量少.结构精简.语义清新. 代码量少,浏览器端下载时间就会更短: 语义清晰就会对搜索引擎