分类 Web开发 下的文章

书上看的代码例子,贴一下内容。
visit.php

<?php
interface Visit
{
    public function go();
}

class Leg implements Visit
{
    public function go()
    {
        echo "wait to Tibet!!!";
    }
}

class Car implements Visit
{
    public function go()
    {
        echo "drive car to Tibet!!!";
    }
}

class Train implements Visit
{
    public function go()
    {
        echo "go to Tibet by train!!!";
    }
}
<?php
include('visit.php');

class Container
{
    protected $bindings = [];

    public function bind($abstract, $concrete = null, $shared = false)
    {
        if (! $concrete instanceof Closure){
            $concrete = $this->getClosure($abstract, $concrete);
        }
        $this->bindings[$abstract] = compact('concrete', 'shared');
        print_r($this->bindings);
    }

    protected function getClosure($abstract, $concrete)
    {
        return function($c) use ($abstract, $concrete)
        {
            $method = ($abstract == $concrete) ? 'build' : 'make';
            return $c->$method($concrete);
        };
    }

    public function make($abstract)
    {
        $concrete = $this->getConcrete($abstract);
        if ($this->isBuildable($concrete, $abstract)) {
            $object = $this->build($concrete);
        } else {
            $object = $this->make($concrete);
        }

        return $object;
    }

    protected function isBuildable($concrete, $abstract)
    {
        return $concrete === $abstract || $concrete instanceof Closure;
    }

    protected function getConcrete($abstract)
    {
        if (! isset($this->bindings[$abstract]))
        {
            return $abstract;
        }
        return $this->bindings[$abstract]['concrete'];
    }

    public function build($concrete)
    {
        if($concrete instanceof Closure){
            return $concrete($this);
        }
        echo "new ";
        var_dump($concrete);
        $reflector = new ReflectionClass($concrete);

        if (!$reflector->isInstantiable()){
            echo $message = "Target [$concrete] is not instantiable.";
        }

        $constructor = $reflector->getConstructor();

        if (is_null($constructor)) {
            return new $concrete;
        }
        $dependencies = $constructor->getParameters();
        $instances = $this->getDependencies($dependencies);
        return $reflector->newInstanceArgs($instances);
    }

    protected function getDependencies($parameters)
    {
        $dependencies = [];
        foreach ($parameters as $parameter) {
            $dependency = $parameter->getClass();
            if(is_null($dependency)){
                $dependencies = NULL;
            } else {
                $dependencies[] = $this->resolveClass($parameter);
            }
        }
        return (array) $dependencies;
    }

    protected function resolveClass(ReflectionParameter $parameter)
    {
        return $this->make($parameter->getClass()->name);
    }
}

class Traveller
{
    protected $trafficTool;

    public function __construct(Visit $trafficTool)
    {
        $this->trafficTool = $trafficTool;
    }

    public function visitTibet(){
        $this->trafficTool->go();
    }
}

$app = new Container();

$app->bind("Visit", "Car");
$app->bind("traveller", "Traveller");
//$car = $app->make("Visit");
$tra = $app->make("traveller");
$tra->visitTibet();

以数组的每一个项作为参数,运行异步的函数。需要在等一个运行完之后运行下一个。变成所谓同步。
async模块提供了each这个函数,网上查了下,发现其实自己也可以写一个。

function asynhand(a, callback) {
    console.log('hi', a);
    setTimeout(callback, 2000);
}

var i = 0;
var running = 0;

function each(arr, itera) {
    if (i >= arr.length) return;
    itera(arr[i], () => each(arr, itera));
    i++;
}

list = ['a','b','c','d','e','f'];

each(list, asynhand);

可以同时运行多个,lim为同时运行的限制数量。把回调函数单独写到了一边,用箭头函数感觉不好读。

function asynhand(a, callback) {
    console.log('hi', a);
    setTimeout(callback, 2000);
}

var i = 0;
var running = 0;

function eachlim(arr, itera, lim) {    
    if (i >= arr.length) return;
    itera(arr[i], c);
    running++;
    i++;
    if ( running < lim ) eachlim(arr, itera, lim);

    function c(){
        running--;
        eachlim(arr, itera, lim);
    }
}

list = ['a','b','c','d','e','f'];

eachlim(list, asynhand, 3);

以前的很多文档都是chm格式的,离线也方便浏览。现在很多开发文档都放在网上了,只要有网查看起来也方便,但是搜索速度没有离线的快。

介绍

zeal项目页面:https://github.com/zealdocs/zeal

zeal 是个比较好的离线文档的浏览器,使用的是macos下的一个离线文档软件的文档资源,所以还需要下文档。

zeal软件托管在github上,release里有编译好的安装包。

碰到的问题

如果浏览MDN的文档有问题,可以下载自动化里最新编译的版本,在项目文档的链接里能找到。

如果下载不了文档,可以尝试设置代理。

原文:https://developer.mozilla.org/docs/Glossary/Primitive

In JavaScript, a primitive (primitive value, primitive data type) is data that is not an object and has no methods. There are 6 primitive data types: string, number, bigint, boolean, undefined, and symbol. There also is null, which is seemingly primitive, but indeed is a special case for every Object: and any structured type is derived from null by the Prototype Chain.

Most of the time, a primitive value is represented directly at the lowest level of the language implementation.

All primitives are immutable, i.e., they cannot be altered. It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned a new value, but the existing value can not be changed in the ways that objects, arrays, and functions can be altered.

Example

This example will help you understand the fact that primitive values are immutable.

JavaScript

// Using a string method doesn't mutate the string
var bar = "baz";
console.log(bar);               // baz
bar.toUpperCase();
console.log(bar);               // baz

// Using an array method mutates the array
var foo = \[\];
console.log(foo);               // \[\]
foo.push("plugh");
console.log(foo);               // \["plugh"\]

// Assignment gives the primitive a new (not a mutated) value
bar = bar.toUpperCase();       // BAZ

A primitive can be replaced, but it can't be directly altered.

Another Example [ Step-by-step ]

The following example will help you go through how JavaScript deals with Primitives.

Primitive

// The Primitive
let foo = 5;

// Defining a function that should change the Primitive value
function addTwo(num) {
   num += 2;
}
// Another function trying to do the same thing
function addTwo_v2(foo) {
   foo += 2;
}

// Calling our first function while passing our Primitive as an argument
addTwo(foo);
// Getting the current Primitive value
console.log(foo);   // 5

// Trying again with our second function...
addTwo_v2(foo);
console.log(foo);   // 5

Did you expect it to be 7 instead of 5? If so, read how this code runs:

  • For both the addTwo and addTwo_v2 functions calls, JavaScript looks up the value for the identifier foo. It correctly finds our variable instantiated with our first statement
  • After finding it, the expression is evaluated, foo is replaced by 5 and the JavaScript engine passes that value to the functions as an argument
  • Before executing the statements inside the functions' bodies, JavaScript takes a copy of the original passed argument (which is a primitive) and creates a local copy. These copies, existing only inside the functions' scopes, are accessible via the identifiers we specified in the functions' definitions (num for addTwo, foo for addTwo_v2)
  • Then, the functions' statements are executed:

    • In the first function, a local num variable had been created. We are increasing its value by 2, not the original foo's value!
    • In the second function, a local foo variable had been created. We are increasing its value by 2, not the original (external) foo's value! Also, in this situation, the external foo variable cannot be accessed directly. This is because of JavaScript's lexical scoping and the resulting variable shadowing. The local foo hides the external foo. For more information, see Closures. (Note that window.foo could still be used to access the external foo variable.)
  • In conclusion, any changes inside our functions won't affect the ORIGINAL foo at all, as we are working on our copies of it

That's why Primitives are immutable - instead of working on them directly, we're working on a copy, without affecting the original.

Primitive wrapper objects in JavaScript

Except for null and undefined, all primitive values have object equivalents that wrap around the primitive values:

  • String for the string primitive.
  • Number for the number primitive.
  • BigInt for the bigint primitive.
  • Boolean for the boolean primitive.
  • Symbol for the symbol primitive.

The wrapper's valueOf() method returns the primitive value.

Learn more

General knowledge

柯里是一个数学家的名字。

比如一个函数有多个参数,要固定函数的某几个参数,这个函数就是就是柯里化后的函数。

《JavaScript the good part》里的例子,一个给function原型添加了一个curry的方法,把add函数的第一个参数固定成1,得到函数add1:

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this; 
};

Function.method('curry', function (  ) {
    var slice = Array.prototype.slice,
        args = slice.apply(arguments),
        that = this;
    return function (  ) {
        return that.apply(null, args.concat(slice.apply(arguments)));
    }; 
});


var add = function (a, b) {
    return a + b; 
};

var add1 = add.curry(1); add1(1);