- 浏览: 45753 次
- 性别:
- 来自: 湖南
最新评论
-
laj12347:
javascript 闭包真是牛逼呀。。看了好久,终于有点 ...
JavaScript: The Good Parts 读书笔记(二) -
mu0001:
赞一个,很不错。以现在的知识来看,先看了第一部分。
JavaScript 数据访问(翻译自High Performance Javascript 第二章) -
e421083458:
得买本书好好看看了!
JavaScript 数据访问(翻译自High Performance Javascript 第二章) -
adamed:
这本书已经有中文版出版了。。到处都可以买到。高性能 javas ...
JavaScript 数据访问(翻译自High Performance Javascript 第二章) -
jiyanliang:
elvishehai 写道来源于那里的呀,写的很不错,学习了. ...
JavaScript 数据访问(翻译自High Performance Javascript 第二章)
5.Inheritance Pattern
- Classical Pattern #1—The Default Pattern
The default method most commonly used is to create an object using the Parent() constructor and assign this object to the Child()’s prototype. Here’s the first implementation of the reusable inherit() function:function inherit(C, P) { C.prototype = new P(); }
It’s important to remember that the prototype property should point to an object, not a function, so it has to point to an instance (an object) created with the parent constructor, not to the constructor itself. In other words, pay attention to the new operator, because you need it for this pattern to work.Later in your application when you use new Child() to create an object, it gets functionality from the Parent() instance via the prototype, as shown in the following example:var kid = new Child(); kid.say(); // "Adam"
Drawbacks When Using Pattern #1
One drawback of this pattern is that you inherit both own properties added to this and prototype properties. Most of the time you don’t want the own properties, because they are likely to be specific to one instance and not reusable.
Another thing about using a generic inherit() function is that it doesn’t enable you to pass parameters to the child constructor, which the child then passes to the parent. Consider this example:var s = new Child('Seth'); s.say(); // "Adam"
This is not what you’d expect. It’s possible for the child to pass parameters to the parent’s constructor, but then you have to do the inheritance every time you need a new child, which is inefficient, because you end up re-creating parent objects over and over.
- Classical Pattern #2—Rent-a-Constructor
This next pattern solves the problem of passing arguments from the child to the parent.It borrows the parent constructor, passing the child object to be bound to this and also forwarding any arguments:function Child(a, c, b, d) { Parent.apply(this, arguments); }
This way you can only inherit properties added to this inside the parent constructor.You don’t inherit members that were added to the prototype.
Using the borrowed constructor pattern, the children objects get copies of the inherited members, unlike the classical #1 pattern where they only get references. The following example illustrates the difference:// a parent constructor function Article() { this.tags = ['js', 'css']; } var article = new Article(); // a blog post inherits from an article object // via the classical pattern #1 function BlogPost() {} BlogPost.prototype = article; var blog = new BlogPost(); // note that above you didn't need `new Article()` // because you already had an instance available // a static page inherits from article // via the rented constructor pattern function StaticPage() { Article.call(this); } var page = new StaticPage(); alert(article.hasOwnProperty('tags')); // true alert(blog.hasOwnProperty('tags')); // false alert(page.hasOwnProperty('tags')); // true
In this example the child blog object modifies the tags property, and this way it also modifies the parent because essentially both blog.tags and article.tags point to the same array. Changes to page.tags don’t affect the parent article because page.tags is a separate copy created during inheritance.
Multiple Inheritance by Borrowing Constructors
Using the borrowing constructors patterns, it’s possible to implement multiple inheritance simply by borrowing from more than one constructor:function Cat() { this.legs = 4; this.say = function () { return "meaowww"; } } function Bird() { this.wings = 2; this.fly = true; } function CatWings() { Cat.apply(this); Bird.apply(this); } var jane = new CatWings(); console.dir(jane);
Pros and Cons of the Borrowing Constructor Pattern
The drawback of this pattern is obviously that nothing from the prototype gets inherited and, as mentioned before, the prototype is the place to add reusable methods and properties, which will not be re-created for every instance.
A benefit is that you get true copies of the parent’s own members, and there’s no risk that a child can accidentally overwrite a parent’s property.
- Classical Pattern #3—Rent and Set Prototype
Combining the previous two patterns, you first borrow the constructor and then also set the child’s prototype to point to a new instance of the constructor:function Child(a, c, b, d) { Parent.apply(this, arguments); } Child.prototype = new Parent();
The benefit is that the result objects get copies of the parent’s own members and references to the parent’s reusable functionality (implemented as members of the prototype).
The child can also pass any arguments to the parent constructor. This behavior is probably the closest to what you’d expect in Java; you inherit everything there is in the parent, and at the same time it’s safe to modify own properties without the risk of modifying the parent.
A drawback is that the parent constructor is called twice, so it could be inefficient. At the end, the own properties (such as name in our case) get inherited twice.
Let’s take a look at the code and do some testing:// the parent constructor function Parent(name) { this.name = name || 'Adam'; } // adding functionality to the prototype Parent.prototype.say = function () { return this.name; }; // child constructor function Child(name) { Parent.apply(this, arguments); } Child.prototype = new Parent(); var kid = new Child("Patrick"); kid.name; // "Patrick" kid.say(); // "Patrick" delete kid.name; kid.say(); // "Adam"
Unlike the previous pattern, now say() is inherited properly. You can also notice that name is inherited two times, and after we delete the own copy, the one that comes down the prototype chain will shine through.
- Classical Pattern #4—Share the Prototype
The rule of thumb was that reusable members should go to the prototype and not this. Therefore for inheritance purposes, anything worth inheriting should be in the prototype. So you can just set the child’s prototype to be the same as the parent’s prototype:function inherit(C, P) { C.prototype = P.prototype; }
This gives you short and fast prototype chain lookups because all objects actually share the same prototype. But that’s also a drawback because if one child or grandchild somewhere down the inheritance chain modifies the prototype, it affects all parents and grandparents.
- Classical Pattern #5—A Temporary Constructor
The next pattern solves the same-prototype problem by breaking the direct link between parent’s and child’s prototype while at the same time benefiting from the prototype chain.
Below is an implementation of this pattern, where you have an empty function F(), which serves as a proxy between the child and the parent. F()’s prototype property points to the prototype of the parent. The prototype of the child is an instance of the blank function:function inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); }
This pattern has a behavior slightly different from the default pattern (classical pattern #1) because here the child only inherits properties of the prototype. And that’s usually fine, actually preferable, because the prototype is the place for reusable functionality. In this pattern, any members that the parent constructor adds to this are not inherited.
Storing the Superclass
Building on top of the previous pattern, you can add a reference to the original parent. This is like having access to the superclass in other languages and could be handy on occasion.
The property is called uber because “super” is a reserved word and “superclass” may lead the unsuspecting developer down the path of thinking that JavaScript has classes. Here’s an improved implementation of this classical pattern:function inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); C.uber = P.prototype; }
Resetting the Constructor Pointer
One last thing to add to this almost perfect classical inheritance function is to reset the pointer to the constructor function in case you need it down the road.
If you don’t reset the pointer to the constructor, then all children objects will report that Parent() was their constructor, which is not useful. So using the previous implementation of inherit(), you can observe this behavior:// parent, child, inheritance function Parent() {} function Child() {} inherit(Child, Parent); // testing the waters var kid = new Child(); kid.constructor.name; // "Parent" kid.constructor === Parent; // true
The constructor property is rarely used but could be convenient for runtime introspection of objects. You can reset it to point to the expected constructor function without affecting the functionality because this property is mostly informational.
The final Holy Grail version of this classical inheritance pattern will look like so:function inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); C.uber = P.prototype; C.prototype.constructor = C; }
A function similar to this exists in the YUI library (and probably other libraries) and brings the classical inheritance to a language without classes, if you decide that this is the best approach for your project.
A common optimization of the Holy Grail pattern is to avoid creating the temporary (proxy) constructor every time you need inheritance. It’s sufficient to create it once and only change its prototype. You can use an immediate function and store the proxy function in its closure:var inherit = (function () { var F = function () {}; return function (C, P) { F.prototype = P.prototype; C.prototype = new F(); C.uber = P.prototype; C.prototype.constructor = C; } }());
Klass
Many JavaScript libraries emulate classes, introducing new sugar syntax. The implementations differ but there are often some commonalities, including the following:
• There’s a convention on how to name a method, which is to be considered the constructor of the class, for example initialize, _init, or something similar and which gets called automatically.
• Classes inherit from other classes.
• There’s access to the parent class (superclass) from within the child class.
Without going into too much detail, let’s see an example implementation of simulated classes in JavaScript. First, how will the solution be used from the client’s perspective?var Man = klass(null, { __construct: function (what) { console.log("Man's constructor"); this.name = what; }, getName: function () { return this.name; } });
The syntax sugar comes in the form of a function called klass(). In some implementations you may see it as Klass() constructor or as augmented Object.prototype, but in this example, let’s keep it a simple function.
The function takes two parameters: a parent class to be inherited and implementation of the new class provided by an object literal. Influenced by PHP, let’s establish the convention that the class’s constructor must be a method called __construct. In the preceding snippet, a new class called Man is created and doesn’t inherit from anything (which means inherit from Object behind the scenes). The Man class has an own property name created inside __construct and a method getName(). The class is a constructor function, so the following will still work (and will look just like a class instantiation):var first = new Man('Adam'); // logs "Man's constructor" first.getName(); // "Adam"
Finally, let’s see how the klass() function can be implemented:var klass = function (Parent, props) { var Child, F, i; // 1. // new constructor Child = function () { if (Child.uber && Child.uber.hasOwnProperty("__construct")) { Child.uber.__construct.apply(this, arguments); } if (Child.prototype.hasOwnProperty("__construct")) { Child.prototype.__construct.apply(this, arguments); } }; // 2. // inherit Parent = Parent || Object; F = function () {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.uber = Parent.prototype; Child.prototype.constructor = Child; // 3. // add implementation methods for (i in props) { if (props.hasOwnProperty(i)) { Child.prototype[i] = props[i]; } } // return the "class" return Child; };
The klass() implementation has three interesting and distinct parts:
1. A Child() constructor function is created. This is the function that will be returned at the end and will be used as a class. In this function the __construct method is called if it exists. Also before that the parent’s __construct is called (again, if it exists) using the static uber property. There might be cases when uber is not defined—when you inherit from Object for example, as the case was with the Man class definition.
2. The second part takes care of the inheritance bit. It’s simply using the classical inheritance’s Holy Grail pattern discussed in the previous section of the chapter. There’s only one new thing: setting the Parent to Object if no Parent was passed to inherit from.
3. The final section is looping through all the implementation methods (such as __construct and getName in the examples), which are the actual definition of the class and adding them to the prototype of Child.
When to use such a pattern? Well, it’s actually better if you avoid it, because it brings the whole confusing notion of classes, which don’t technically exist in the language. It adds new syntax and new rules to learn and remember. That said, if you or the team feel at ease with classes and at the same time feel uncomfortable with prototypes, then this could be something to explore. This pattern allows you to forget about the prototypes completely, and the good thing is you can tweak the syntax and the conventions to resemble another of your favorite languages.
- Prototypal Inheritance
Let’s start the discussion of “modern” classless patterns with a pattern called prototypal inheritance. In this pattern there are no classes involved; here objects inherit from other objects. You can think about it this way: you have an object that you would like to reuse and you want to create a second object that gets its functionality from the first one.// object to inherit from var parent = { name: "Papa" }; // the new object var child = object(parent); // testing alert(child.name); // "Papa"
In the preceding snippet, you have an existing object called parent created with the object literal, and you want to create another object called child that has the same properties and methods as the parent. The child object was created with a function called object(). This function doesn’t exist in JavaScript (not to be mistaken with the constructor function Object()), so let’s see how you can define it.
Similarly to the classical Holy Grail, you would use an empty temporary constructor function F(). You then set the prototype of F() to be the parent object. Finally, you return a new instance of the temporary constructor:function object(o) { function F() {} F.prototype = o; return new F(); }
In the prototypal inheritance pattern, your parent doesn’t need to be created with the literal notation (although that is probably the more common way). You can have constructor functions create the parent. Note that if you do so, both “own” properties and properties of the constructor’s prototype will be inherited:// parent constructor function Person() { // an "own" property this.name = "Adam"; } // a property added to the prototype Person.prototype.getName = function () { return this.name; }; // create a new person var papa = new Person(); // inherit var kid = object(papa); // test that both the own property // and the prototype property were inherited kid.getName(); // "Adam"
In another variation of this pattern you have the option to inherit just the prototype object of an existing constructor. Remember, objects inherit from objects, regardless of how the parent objects were created. Here’s an illustration using the previous example, slightly modified:// parent constructor function Person() { // an "own" property this.name = "Adam"; } // a property added to the prototype Person.prototype.getName = function () { return this.name; }; // inherit var kid = object(Person.prototype); typeof kid.getName; // "function", because it was in the prototype typeof kid.name; // "undefined", because only the prototype was inherited
Addition to ECMAScript 5
In ECMAScript 5, the prototypal inheritance pattern becomes officially a part of the language. This pattern is implemented through the method Object.create(). In other words, you won’t need to roll your own function similar to object(); it will be built into the language:var child = Object.create(parent);
Object.create() accepts an additional parameter, an object. The properties of the extra object will be added as own properties of the new child object being returned. This is a convenience that enables you to inherit and build upon the child object with one method call. For example:var child = Object.create(parent, { age: { value: 2 } // ECMA5 descriptor }); child.hasOwnProperty("age"); // true
- Inheritance by Copying Properties
Let’s take a look at another inheritance pattern—inheritance by copying properties. In this pattern, an object gets functionality from another object, simply by copying it.Here’s an example implementation of a sample function extend() that does that:function extend(parent, child) { var i; child = child || {}; for (i in parent) { if (parent.hasOwnProperty(i)) { child[i] = parent[i]; } } return child; }
It’s a simple implementation, just looping through the parent’s members and copying them over. In this implementation child is optional; if you don’t pass an existing object to be augmented, then a brand new object is created and returned:var dad = {name: "Adam"}; var kid = extend(dad); kid.name; // "Adam"
The implementation given is a so-called “shallow copy” of the object. A deep copy on the other hand would mean checking if the property you’re about to copy is an object or an array, and if so, recursively iterating through its properties and copying them as well. With the shallow copy (because objects are passed by reference in JavaScript), if you change a property of the child, and this property happens to be an object, then you’ll be modifying the parent as well.
Now let’s modify the extend() function to make deep copies. All you need is to check if a property’s type is an object, and if so, recursively copy its properties. Another check you need is if the object is a true object or if it’s an array. Let’s use the check for arrayness discussed in Chapter 3. So the deep copy version of extend() would look like so:function extendDeep(parent, child) { var i, toStr = Object.prototype.toString, astr = "[object Array]"; child = child || {}; for (i in parent) { if (parent.hasOwnProperty(i)) { if (typeof parent[i] === "object") { child[i] = (toStr.call(parent[i]) === astr) ? [] : {}; extendDeep(parent[i], child[i]); } else { child[i] = parent[i]; } } } return child; }
Now testing the new implementation gives us true copies of objects, so child objects don’t modify their parents:var dad = { counts: [1, 2, 3], reads: {paper: true} }; var kid = extendDeep(dad); kid.counts.push(4); kid.counts.toString(); // "1,2,3,4" dad.counts.toString(); // "1,2,3" dad.reads === kid.reads; // false kid.reads.paper = false; kid.reads.web = true; dad.reads.paper; // true
This property copying pattern is simple and widely used; for example, Firebug (Firefox extensions are written in JavaScript) has a method called extend() that makes shallowcopies and jQuery’s extend() creates a deep copy. YUI3 offers a method called Y.clone(), which creates a deep copy and also copies over functions by binding them to the child object. (There will be more on binding later in this chapter.) It’s worth noting that there are no prototypes involved in this pattern at all; it’s only about objects and their own properties.
- Borrowing Methods
Sometimes it may happen that you only like one or two methods of an existing object.You want to reuse them, but you don’t really want to form a parent-child relationship with that object. You want to use just the methods you like, without inheriting all the other methods that you’ll never need. This is possible with the borrowing methods pattern, which benefits from the function methods call() and apply(). You’ve seen this pattern already in the book and even in this chapter in the implementation of extendDeep(), for example.
As you know, functions in JavaScript are objects, and they come with some interesting methods of their own, such as call() and apply(). The only difference between the two is that one takes an array of parameters to be passed to the method being called, and the other one takes parameters one by one. You can use these methods to borrow functionality from existing objects:// call() example notmyobj.doStuff.call(myobj, param1, p2, p3); // apply() example notmyobj.doStuff.apply(myobj, [param1, p2, p3]);
Here you have an object called myobj and you know that some other object called notmyobj has this useful method called doStuff(). Instead of going through the inheritance hassle and inheriting a number of methods your myobj will never need, you can simply borrow the method doStuff() temporarily.
You pass your object and any parameters, and the borrowed method binds your object as its own this. Basically, your object pretends to be the other object for a bit to benefit from the method you like. It’s like getting an inheritance but without paying the inheritance tax (where the “tax” comes in the form of extra properties and methods you have no need for).
Example: Borrow from Array
A common use for this pattern is borrowing array methods.Arrays have useful methods, which array-like objects such as arguments don’t have. So arguments can borrow array methods, such as the method slice(). Here’s one example:function f() { var args = [].slice.call(arguments, 1, 3); return args; } // example f(1, 2, 3, 4, 5, 6); // returns [2,3]
Borrow and Bind
When borrowing methods either through call()/apply() or through simple assignment, the object that this points to inside of the borrowed method is determined based on the call expression. But sometimes it’s best to have the value of this “locked” or bound to a specific object and predetermined in advance(预先决定调用者是谁).
Let’s see an example. There’s an object called one that has a say() method:var one = { name: "object", say: function (greet) { return greet + ", " + this.name; } }; // test one.say('hi'); // "hi, object"
Now another object two doesn’t have a say() method, but it can borrow it from one:
var two = { name: "another object" }; one.say.apply(two, ['hello']); // "hello, another object"
In the preceding case, this inside say() pointed to two and this.name was therefore “another object.” But what about scenarios in which you assign the function pointer to a global variable or you pass the function as a callback? In client-side programming there are a lot of events and callbacks, so that does happen a lot:// assigning to a variable // `this` will point to the global object var say = one.say; say('hoho'); // "hoho, undefined" // passing as a callback var yetanother = { name: "Yet another object", method: function (callback) { return callback('Hola'); } }; yetanother.method(one.say); // "Holla, undefined"
In both of those cases this inside say() was pointing to the global object, and the whole snippet didn’t work as expected. To fix (in other words, bind) an object to a method,we can use a simple function like this:function bind(o, m) { return function () { return m.apply(o, [].slice.call(arguments)); }; }
This bind() function accepts an object o and a method m, binds the two together, and then returns another function. The returned function has access to o and m via a closure.Therefore even after bind() returns, the inner function will have access to o and m, which will always point to the original object and method. Let’s create a new function using bind():var twosay = bind(two, one.say); twosay('yo'); // "yo, another object"
As you can see, even though twosay() was created as a global function, this didn’t point to the global object, but it pointed to object two, which was passed to bind(). Regardless of how you call twosay(), this will always be bound to two. The price you pay for the luxury of having a bind is the additional closure.
Function.prototype.bind()
ECMAScript 5 adds a method bind() to Function.prototype, making it just as easy to use as apply() and call(). So you can do expressions like:var newFunc = obj.someFunc.bind(myobj, 1, 2, 3);
This means bind together someFunc() and myobj and also prefill the first three arguments that someFunc() expects.Let’s see how you can implement Function.prototype.bind() when your program runs in pre-ES5 environments:if (typeof Function.prototype.bind === "undefined") { Function.prototype.bind = function (thisArg) { var fn = this, slice = Array.prototype.slice, args = slice.call(arguments, 1); return function () { return fn.apply(thisArg, args.concat(slice.call(arguments))); }; }; }
This implementation probably looks a bit familiar; it’s using partial application and concatenating the list of arguments—those passed to bind() (except the first) and those passed when the new function returned by bind() is called later. Here’s an example use:var twosay2 = one.say.bind(two); twosay2('Bonjour'); // "Bonjour, another object"
- Last
Remember that code reuse is the goal, and inheritance is just one of the ways to accomplish that goal.
发表评论
-
High Performance JavaScript 读书笔记(五)
2011-02-27 21:24 2276五.Strings and Regular Expressio ... -
High Performance JavaScript 读书笔记(六)
2011-02-27 20:49 2661六.Responsive Interfaces There ... -
High Performance JavaScript 读书笔记(四)
2011-02-27 19:50 1216四.Algorithms and Flow Control ... -
High Performance JavaScript 读书笔记(三)
2011-02-27 14:43 1727三.DOM Scripting DOM scripting ... -
High Performance JavaScript 读书笔记(一)
2011-02-27 13:44 1613一.Loading and Execution JavaS ... -
JavaScript 数据访问(翻译自High Performance Javascript 第二章)
2011-02-27 13:21 1933计算机科学中一 ... -
JavaScript Patterns 读书笔记(七)
2011-02-15 20:32 14437.Client Pattern DOM Access ... -
JavaScript Patterns 读书笔记(六)
2011-02-15 19:38 12626.Design Pattern Singleton ... -
JavaScript Patterns 读书笔记(四)
2011-02-15 18:19 11884.Function Pattern Namespace ... -
JavaScript Patterns 读书笔记(二)
2011-02-14 21:20 1166二.Object Object Constructor C ... -
JavaScript Patterns 读书笔记(三)
2011-02-14 21:19 1463三.Function Background The ... -
JavaScript Patterns 读书笔记(一)
2011-02-14 20:09 1664一.Global 全局域中的this = window.m ... -
JavaScript: The Good Parts 读书笔记(五)
2011-01-27 12:56 2091五.Javascript 总结 语 ... -
JavaScript: The Good Parts 读书笔记(四)
2011-01-27 11:37 1002四.数组与正则表达式 ... -
JavaScript: The Good Parts 读书笔记(三)
2011-01-26 23:38 1408三.继承 概述 Javascr ... -
JavaScript: The Good Parts 读书笔记(二)
2011-01-26 23:01 1784二.函数 JS 中函数亦是对象 使用字面变量表面 ... -
JavaScript: The Good Parts 读书笔记(一)
2011-01-26 21:44 1290一.基础特性 在浏览器中,每个<script> ...
相关推荐
其次,笔记可能会深入讲解设计模式(Design Patterns),这是软件设计中的重要概念,如工厂模式、单例模式、观察者模式等。这些模式为解决常见的软件设计问题提供了标准化的解决方案,是提高代码复用性和灵活性的...
这篇博客涵盖了前端开发的多个重要知识点,包括心法、LeetCode算法练习、框架原理、计算机网络、设计模式、自造轮子以及读书笔记等。以下是对这些内容的详细阐述: **心法**: 在前端开发中,心法指的是开发者应该...
它包含一些经典的GoF设计模式的集合,这些模式使用JavaScript和ES6类以及Node.js API在JavaScript中实现。 感谢并非常欢迎您做出贡献,调整现有模式的README.md,或改进示例或添加新模式。 只需做出一个叉子,进行...
本笔记主要依据曾探的著作《JavaScript设计模式与开发实践》进行整理,涵盖了设计模式的基本知识,以及创建、结构、行为、状态和策略等模式的应用。 **基础知识** 在深入设计模式之前,我们需要理解一些基本概念,...
2. `languages/` - 不同编程语言的学习笔记,如Python、Java、JavaScript等。 3. `frameworks/` - 使用的各种框架的笔记,如Django、React、Angular等。 4. `algorithms/` - 数据结构和算法的学习笔记,包括实现和...
2. **GWT_speakernoted.pdf**:这可能是关于Google Web Toolkit (GWT)的演讲笔记,GWT是一个开源的Java开发工具,它允许开发者使用Java编写客户端Web应用,然后编译成优化的JavaScript代码。GWT支持Ajax特性,并且...
8. **Design_Patterns**:讨论软件设计模式,如单例模式、工厂模式等在前端开发中的应用。 9. **Interview_Tips**:提供面试技巧,如何回答行为问题,如何展示自己的项目经验等。 10. **Projects**:可能包含一些...
都是参考众多文章归纳整理学习而写的,文章包括了HTML基础、CSS基础、JavaScript基础与拓展、Browser浏览器相关、Vue使用与分析、React使用与分析、Plugin插件相关、Patterns设计模式、Linux命令、LeetCode题解等...
都是参考众多文章归纳整理学习而写的,文章包括了HTML基础、CSS基础、JavaScript基础与拓展、Browser浏览器相关、Vue使用与分析、React使用与分析、Plugin插件相关、Patterns设计模式、Linux命令、LeetCode题解等...
除了每日一题的学习笔记之外还有一些做项目时的记录以及遇到的坑等,对于技术相关的文章基本都是参考众多文章归纳整理学习而写的,文章包括了HTML基础、CSS基础、JavaScript基础与拓展、Browser浏览器相关、Vue使用...
项目介绍小路描述CSS CSS世界练习代码UIAndAnamited 画布,SVG,三等练习代码算法算法练习成分组件封装练习源代码原始解析笔记数据结构斑点结构DesignPatterns |设计模式演示自己实现的一些好玩的小演示
女性笔记 :clapping_hands:欢迎star,也不容易搞丢链接哦! :clapping_hands: 欢迎加入明星,失去联系并不容易!它是什么?我是在参加2020年秋招的时候,实际上那时候往前2个月我才开始系统接触前沿领域。为了快速...
单页图书项目使用项目的IT笔记(Java,Linux,密码学,云,体系结构等)的超级备忘单。克隆并执行下一行以启动本地Web服务器。 $ ./httpServer.py仅需要服务器,以避免浏览器禁用从文件系统路径加载脚本的麻烦。 ...