#837
展开↯#839
作者:广西南宁市
内容包含视频,视频不见。 #,广西南宁市,2017-11-02,20:12:10,
外链图片bug,非src图片img
外链图片bug,非src图片img
$content=$s['content'];
$content=str_ireplace("data-src=","src=",$content);
preg_match_all("/\<img.*?src\=\"(.*?)\"[^>]*>/i", $content, $match); Run code
Cut to clipboard
文章:Weiphp后台群发推送微信公众号文章插件【基础/单篇推送】 发表时间:2017-11-02, 19:48:20
#840
作者:广西南宁市
微信订阅号中用户的openid两种方式获得。
1.用户发消息给你,你收到的xml中有user的openid
2.或者去拉取用户列表
1.用户发消息给你,你收到的xml中有user的openid
2.或者去拉取用户列表
文章:Weiphp后台群发推送微信公众号文章插件【基础/单篇推送】 发表时间:2017-11-02, 15:34:32
#841
作者:广西南宁市
微信订阅号点击菜单栏获取用户信息
微官网微信订阅号通过点击菜单栏获取openid用户信息
有的认证订阅号有网页授权获取用户基本信息
有的认证订阅号没有网页授权获取用户基本信息
认证服务号是有这个接口权限的,所以用认证服务号开发,不用担心这个接口权限问题
微官网微信订阅号通过点击菜单栏获取openid用户信息
有的认证订阅号有网页授权获取用户基本信息
有的认证订阅号没有网页授权获取用户基本信息
认证服务号是有这个接口权限的,所以用认证服务号开发,不用担心这个接口权限问题
文章:Weiphp后台群发推送微信公众号文章插件【基础/单篇推送】 发表时间:2017-11-02, 15:33:58
#842
作者:广西南宁市
weiphp 微信登录失败 授权回调域名校验出错,错误码:10003
上线前清空
关注粉丝数据

清空会员数据,保留管理员登录账号

#,广西南宁市,2017-11-02,10:23:42,
禁用后台需要服务号接口权限插件


#,广西南宁市,2017-11-02,10:24:50, 微信登录获取用户信息错误:订阅号没有相关接口权限,需要服务号。 #,广西南宁市,2017-11-02,11:47:59,
当用户和订阅号有互动的时候可以获取用户的openid,比如关注事件,点击自定义菜单事件
订阅号开放了获取用户基本信息的接口,但openid怎么取?
即时认证 也无法获取 订阅号没有此功能
但可以通过再申请一个服务号用认证服务号获取,然后通过后台同步到订阅号统计页
#,广西南宁市,2017-11-02,11:48:52,
上线前清空
关注粉丝数据
清空会员数据,保留管理员登录账号
禁用后台需要服务号接口权限插件
当用户和订阅号有互动的时候可以获取用户的openid,比如关注事件,点击自定义菜单事件
订阅号开放了获取用户基本信息的接口,但openid怎么取?
即时认证 也无法获取 订阅号没有此功能
但可以通过再申请一个服务号用认证服务号获取,然后通过后台同步到订阅号统计页
\Application\Common\Common\function.phpRun code
Cut to clipboard
// 判断公众号的类型:是订阅号还是服务号
function get_token_type($token = '') {
empty ( $token ) && $token = get_token ();//修复订阅号 服务号判断权限bug
$info = get_token_appinfo ( $token );
return intval ( $info ['type'] );
}Run code
Cut to clipboard
function OAuthWeixin($callback) {
$isWeixinBrowser = isWeixinBrowser ();
$info = get_token_appinfo ();
if (! $isWeixinBrowser || empty ( $info ['appid'] )) {
redirect ( $callback . '&openid=-1' );
}
$param ['appid'] = $info ['appid'];
//dump($_GET ['state']);exit;
//$_GET ['getOpenId']=1;
if (! isset ( $_GET ['getOpenId'] ) && $info['type']==1) { //修复订阅号 服务号判断权限bug
$param ['redirect_uri'] = $callback . '&getOpenId=1';
$param ['response_type'] = 'code';
$param ['scope'] = 'snsapi_base';
$param ['state'] = 123;
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?' . http_build_query ( $param ) . '#wechat_redirect';
redirect ( $url );
} elseif ($_GET ['state']) {
$param ['secret'] = $info ['secret'];
$param ['code'] = I ( 'code' );
$param ['grant_type'] = 'authorization_code';
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?' . http_build_query ( $param );
$content = file_get_contents ( $url );
$content = json_decode ( $content, true );
redirect ( $callback . '&openid=' . $content ['openid'] );
}
}Run code
Cut to clipboard
文章:scope参数错误或没有scope权限 发表时间:2017-11-02, 10:11:24
#843
作者:广西南宁市
box-sizing语法
box-sizing:content-box | border-box
默认值:content-box
适用于:所有接受 <' width '> 和 <' height '> 的元素
继承性:无
动画性:否
计算值:指定值
box-sizing取值
content-box:padding和border不被包含在定义的width和height之内。对象的实际宽度等于设置的width值和border、padding之和,即 ( Element width = width + border + padding ) 此属性表现为标准模式下的盒模型。
border-box:padding和border被包含在定义的width和height之内。对象的实际宽度就等于设置的width值,即使定义有border和padding也不会改变对象的实际宽度,即 ( Element width = width ) 此属性表现为怪异模式下的盒模型。
box-sizing说明
设置或检索对象的盒模型组成模式。(标准模式和怪异模式)
box-sizing:content-box | border-box
默认值:content-box
适用于:所有接受 <' width '> 和 <' height '> 的元素
继承性:无
动画性:否
计算值:指定值
box-sizing取值
content-box:padding和border不被包含在定义的width和height之内。对象的实际宽度等于设置的width值和border、padding之和,即 ( Element width = width + border + padding ) 此属性表现为标准模式下的盒模型。
border-box:padding和border被包含在定义的width和height之内。对象的实际宽度就等于设置的width值,即使定义有border和padding也不会改变对象的实际宽度,即 ( Element width = width ) 此属性表现为怪异模式下的盒模型。
box-sizing说明
设置或检索对象的盒模型组成模式。(标准模式和怪异模式)
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>box-sizing拯救了我们的布局</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.wrapper {
width: 960px;
margin-left: auto;
margin-right: auto;
color:#fff;
font-size: 30px;
text-align: center;
background: #ccc;
}
#header {
height: 100px;
background: #38382e;
margin-bottom: 10px;
border: 10px solid red;
padding: 10px;
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-o-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.sidebar {
float: left;
width: 220px;
margin-right: 20px;
margin-bottom: 10px;
height: 300px;
background: #5d33cf;
border: 10px solid red;
padding: 10px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-o-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.content {
float: left;
width: 720px;
height: 300px;
background: #c8ca30;
margin-bottom: 10px;
border: 10px solid red;
padding: 10px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-o-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
#footer {
background: #cc4ad5;
height: 100px;
text-align: center;
clear: both;
border: 10px solid red;
padding: 10px;
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-o-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="wrapper">
<div id="header">页眉</div>
<div class="sidebar">侧边栏</div>
<div class="content">主内容</div>
<div id="footer">页脚</div>
</div>
</body>
</htmlRun code
Cut to clipboard
文章:理解box-sizing布局 发表时间:2017-11-01, 18:32:58
#844
作者:广西南宁市
PHP队列的实现 算法
此队列算法中有两个类一个是data类,这个类是存放数据;第二个是queue也就是队列类这个就是队列的一些操作。
首先队列里包含front(队列的头,也就是出队是要出去的) rear(队列的尾部在这里永远指向0) queue(存放所有入队的data对像,queue中默认存在一个元素当空时front和rear都指向他) maxsize(队列的长度)四个属性
应用说明:
1初始化队列:生成一个队列传入一个参数作为maxsize初始化队列把rear设为0 ,front设为0此时queue中只有0号元素rear和front都指向他
2.入队:判断队列是否已满(front-rear==maxsize),如果满提示,若果没满先让front+1,然后让所有队列中的元素像前移动一位(也就是给新来的让出队尾位置),然后生成data对象插入到队尾+1的位置。此时入队成功!
3.出队:判断队列是否为空(front==rear),如空提示,如不为空,删除front指向的对象,front-1(向后移动一位),出队成功!
此队列算法中有两个类一个是data类,这个类是存放数据;第二个是queue也就是队列类这个就是队列的一些操作。
首先队列里包含front(队列的头,也就是出队是要出去的) rear(队列的尾部在这里永远指向0) queue(存放所有入队的data对像,queue中默认存在一个元素当空时front和rear都指向他) maxsize(队列的长度)四个属性
应用说明:
1初始化队列:生成一个队列传入一个参数作为maxsize初始化队列把rear设为0 ,front设为0此时queue中只有0号元素rear和front都指向他
2.入队:判断队列是否已满(front-rear==maxsize),如果满提示,若果没满先让front+1,然后让所有队列中的元素像前移动一位(也就是给新来的让出队尾位置),然后生成data对象插入到队尾+1的位置。此时入队成功!
3.出队:判断队列是否为空(front==rear),如空提示,如不为空,删除front指向的对象,front-1(向后移动一位),出队成功!
<?php
/**
* php队列算法
*
* Create On 2010-6-4
* Author Been
* QQ:281443751
* Email:binbin1129@126.com
**/
class data {
//数据
private $data;
public function __construct($data){
$this->data=$data;
echo $data.":哥进队了!<br>";
}
public function getData(){
return $this->data;
}
public function __destruct(){
echo $this->data.":哥走了!<br>";
}
}
class queue{
protected $front;//队头
protected $rear;//队尾
protected $queue=array('0'=>'队尾');//存储队列
protected $maxsize;//最大数
public function __construct($size){
$this->initQ($size);
}
//初始化队列
private function initQ($size){
$this->front=0;
$this->rear=0;
$this->maxsize=$size;
}
//判断队空
public function QIsEmpty(){
return $this->front==$this->rear;
}
//判断队满
public function QIsFull(){
return ($this->front-$this->rear)==$this->maxsize;
}
//获取队首数据
public function getFrontDate(){
return $this->queue[$this->front]->getData();
}
//入队
public function InQ($data){
if($this->QIsFull())echo $data.":我一来咋就满了!(队满不能入队,请等待!)<br>";
else {
$this->front++;
for($i=$this->front;$i>$this->rear;$i--){
//echo $data;
if($this->queue[$i])unset($this->queue[$i]);
$this->queue[$i]=$this->queue[$i-1];
}
$this->queue[$this->rear+1]=new data($data);
//print_r($this->queue);
//echo $this->front;
echo '入队成功!<br>';
}
}
//出队
public function OutQ(){
if($this->QIsEmpty())echo "队空不能出队!<br>";
else{
unset($this->queue[$this->front]);
$this->front--;
//print_r($this->queue);
//echo $this->front;
echo "出队成功!<br>";
}
}
}
$q=new queue(3);
$q->InQ("小苗");
$q->InQ('马帅');
$q->InQ('溜冰');
$q->InQ('张世佳');
$q->OutQ();
$q->InQ("周瑞晓");
$q->OutQ();
$q->OutQ();
$q->OutQ();
$q->OutQ();Run code
Cut to clipboard
文章:Windows环境安装PHP redis扩展 发表时间:2017-11-01, 18:26:16
#845
作者:广西南宁市
PHP实现队列及队列原理
队列是一种线性表,按照先进先出的原则进行的:
PHP实现队列原理看看各语言实现队列的方法:
各语言实现队列的方法PHP实现队列:第一个元素作为队头,最后一个元素作为队尾
什么是双端队列(或双向队列)Deque,全名double-ended queue?
即元素可以在队列的任意一段入队或出队,如果我们把这些方法叫做insertLeft()和insertRight(),以及removeLeft()和removeRight()。如果严格禁止调用insertLeft()和removeLeft()方法(或禁用右段的操作),双端队列功能就和栈一样。禁止调用insertLeft()和removeRight()(或相反的另一对方法),它的功能就和队列一样了。双端队列与栈或队列相比,是一种多用途的数据结构。
PHP实现双端队列:
队列的用途:
队列可以很好地异步处理数据传送和存储,当你频繁地向数据库中插入数据、频繁地向搜索引擎提交数据,就可采取队列来异步插入。另外,还可以将较慢的处理逻辑、有并发数量限制的处理逻辑,通过消息队列放在后台处理,例如FLV视频转换、发送手机短信、发送电子邮件等。
队列是一种线性表,按照先进先出的原则进行的:
PHP实现队列原理看看各语言实现队列的方法:
各语言实现队列的方法PHP实现队列:第一个元素作为队头,最后一个元素作为队尾
<?php
/**
* 队列就是这么简单
*
* @link http://www.phpddt.com
*/
$array = array('PHP', 'JAVA');
array_push($array, 'PYTHON'); //入队列
array_shift($array); //出队列
Run code
Cut to clipboard
什么是双端队列(或双向队列)Deque,全名double-ended queue?
即元素可以在队列的任意一段入队或出队,如果我们把这些方法叫做insertLeft()和insertRight(),以及removeLeft()和removeRight()。如果严格禁止调用insertLeft()和removeLeft()方法(或禁用右段的操作),双端队列功能就和栈一样。禁止调用insertLeft()和removeRight()(或相反的另一对方法),它的功能就和队列一样了。双端队列与栈或队列相比,是一种多用途的数据结构。
PHP实现双端队列:
<?php
class Deque
{
public $queue = array();
/**(尾部)入队 **/
public function addLast($value)
{
return array_push($this->queue,$value);
}
/**(尾部)出队**/
public function removeLast()
{
return array_pop($this->queue);
}
/**(头部)入队**/
public function addFirst($value)
{
return array_unshift($this->queue,$value);
}
/**(头部)出队**/
public function removeFirst()
{
return array_shift($this->queue);
}
/**清空队列**/
public function makeEmpty()
{
unset($this->queue);
}
/**获取列头**/
public function getFirst()
{
return reset($this->queue);
}
/** 获取列尾 **/
public function getLast()
{
return end($this->queue);
}
/** 获取长度 **/
public function getLength()
{
return count($this->queue);
}
}Run code
Cut to clipboard
队列的用途:
队列可以很好地异步处理数据传送和存储,当你频繁地向数据库中插入数据、频繁地向搜索引擎提交数据,就可采取队列来异步插入。另外,还可以将较慢的处理逻辑、有并发数量限制的处理逻辑,通过消息队列放在后台处理,例如FLV视频转换、发送手机短信、发送电子邮件等。
文章:Windows环境安装PHP redis扩展 发表时间:2017-11-01, 18:24:50
#846
作者:广西南宁市
php redis 并发控制
针对并发控制可以使用 memcacheq ,redis channle 等方式处理
这里我单单的说一下redis 怎么去控制并发
redis控制并发主要采用 redis list api 中的 lPush llen lPop 这三个函数
lLen - 获得列表的长度
lPop - 删除列表的第一个值并返回它
lPush - 插入一个值到列表中,如果列表不存在,新建一个列表
比如我这边现在有个抢购的需求。一个商品只运行抢200个 大概思路如下

每次查看 redis 消息队列 长度是否已经超过 或 = 200 这种写法有可能会有多抢的情况。
所以我们这边后端的单独起一个程序做队列处理。如果说数量太多那就后面的不进行处理操作。

当然。这个前端已经进入队列的用户。你不能告诉人家您已经抢到了。应该让他5分钟后再去看看结果。
这样处理的数量不会去超出。当然如果并发太大的话可以专门寻找处理并发架构,
如果要求用户体验友好那就用socket获取后端处理结果告诉用户是否抢到。redis处理还是蛮快的所以不用担心用户等待时间过长
针对并发控制可以使用 memcacheq ,redis channle 等方式处理
这里我单单的说一下redis 怎么去控制并发
redis控制并发主要采用 redis list api 中的 lPush llen lPop 这三个函数
lLen - 获得列表的长度
lPop - 删除列表的第一个值并返回它
lPush - 插入一个值到列表中,如果列表不存在,新建一个列表
比如我这边现在有个抢购的需求。一个商品只运行抢200个 大概思路如下
每次查看 redis 消息队列 长度是否已经超过 或 = 200 这种写法有可能会有多抢的情况。
所以我们这边后端的单独起一个程序做队列处理。如果说数量太多那就后面的不进行处理操作。
当然。这个前端已经进入队列的用户。你不能告诉人家您已经抢到了。应该让他5分钟后再去看看结果。
这样处理的数量不会去超出。当然如果并发太大的话可以专门寻找处理并发架构,
如果要求用户体验友好那就用socket获取后端处理结果告诉用户是否抢到。redis处理还是蛮快的所以不用担心用户等待时间过长
文章:Windows环境安装PHP redis扩展 发表时间:2017-11-01, 18:23:29
#847
作者:广西南宁市
PHP中利用redis实现消息队列处理高并发请求
将请求存入redis
为了模拟多个用户的请求,使用一个for循环替代
在后台进行数据处理
守护进程
将请求存入redis
为了模拟多个用户的请求,使用一个for循环替代
//redis数据入队操作
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
for($i=0;$i<50;$i++){
try{
$redis->LPUSH('click',rand(1000,5000));
}catch(Exception $e){
echo $e->getMessage();
}
}Run code
Cut to clipboard
在后台进行数据处理
守护进程
//redis数据出队操作,从redis中将请求取出
$redis = new Redis();
$redis->pconnect('127.0.0.1',6379);
while(true){
try{
$value = $redis->LPOP('click');
if(!$value){
break;
}
//var_dump($value)."\n";
/*
* 利用$value进行逻辑和数据处理
*/
}catch(Exception $e){
echo $e->getMessage();
}
}Run code
Cut to clipboard
文章:Windows环境安装PHP redis扩展 发表时间:2017-11-01, 18:22:18
#848
作者:广西南宁市
windows php_redis.dll 官方下载地址 php5x php7x
官方php_redis.dll
http://windows.php.net/downloads/pecl/releases/redis/2.2.7/
官方 linux版本的
https://pecl.php.net/package/redis
官方 php_memcache.dll
http://windows.php.net/downloads/pecl/releases/memcache/3.0.8/
更多
http://windows.php.net/downloads/pecl/
PHP7.1 php_redis.dll
下载地址:http://windows.php.net/downloads/pecl/releases/redis/3.1.2/ Run code
Cut to clipboard
文章:Windows环境安装PHP redis扩展 发表时间:2017-11-01, 18:21:26
#849
作者:广西南宁市
认识js函数对象(Function Object)
认识函数对象(Function Object)
可以用function关键字定义一个函数,对于每个函数可以为其指定一个函数名,通过函
数名来进行调用。这些都是代码给用户的印象,而在JavaScript解释执行的时候,实际上每
个函数都是被维护为一个对象,这就是本小节将要介绍的函数对象(Function Object)。
函数对象与其它用户所定义的对象有着本质的区别,这一类对象被称之为内部对象,例
如日期对象(Date)、数组对象(Array)、字符串对象(String)都是属于内部对象。换句话
说,这些内置对象的构造器是由JavaScript本身所定义的:通过执行new Array()这样的语句
返回一个对象,JavaScript 内部有一套机制来初始化返回的对象,而不是由用户来指定对象
的构造方式。
在 JavaScript中,函数对象对应的类型是Function,正如数组对象对应的类型是Array,
日期对象对应的类型是Date一样,可以通过new Function()来创建一个函数对象,也可以通
过function关键字来创建一个对象。为了便于理解,将函数对象的创建和数组对象的创建来
比较。先看数组对象:下面两行代码的作用是一样的,都是创建一个数组对象myArray:
var myArray=[];
//等价于
var myArray=new Array();
同样,下面的两段代码也是等价的,都是创建一个函数myFunction:
function myFunction(a,b){
return a+b;
}
//等价于
var myFunction=new Function("a","b","return a+b");
现在上面的代码还有些难以理解,但是通过和构造数组对象语句的比较,可以清楚的看
到函数的对象本质,前面介绍的函数声明是上述代码的第一种方式,而在解释器内部,当遇
到这种语法时,就会自动构造一个Function 对象,将函数作为一个内部的对象来存储和运
行。从这里也可以看到,一个函数对象名称(函数变量)和一个普通变量名称具有同样的规
范,都可以通过变量名来引用这个变量,但是函数变量名后面可以跟上括号和参数列表来进
行函数调用。
也许不会有人通过new Function()的形式来创建一个函数,因为一个函数体通常会有多
条语句,如果将它们以一个字符串的形式作为参数传递,那么代码的可读性会非常的差。下
面介绍一下其使用语法:
var funcName=new Function(p1,p2,...,pn,body);
参数的类型都是字符串,p1 到pn表示所创建函数的参数名称列表,body表示所创建函
数的函数体语句,而funcName就是所创建函数的名称了。可以不指定任何参数创建一个空
函数,不指定funcName创建一个无名函数,当然那样的函数什么用处都没有。
需要注意的是,前面说p1 到pn是参数名称的列表,这意味着p1不仅仅只能代表一个
参数,它也可以是一个逗号格开的参数列表,例如下面的定义是等价的:
new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")
JavaScript引入Function类型并提供new Function()这样的语法来创建函数并不是毫无意
义的,在后面可以看到,函数作为一个对象,它本身就可以具有一些方法和属性,而为函数
对象添加属性和方法就必须借助于Function这个类型。
现在已经认识到了函数的本质,它其实是一个内部对象,由JavaScript解释器决定其运
行方式。通过上述代码创建的函数,在程序中可以使用函数名进行调用。于是在本节开头列
出的函数定义问题也得到了解释:它们都是创建函数对象的正确语法。注意直接在函数声明
后面加上括号就表示创建完成后立即进行函数调用,例如:
var i=function (a,b){
return a+b;
}(1,2);
alert(i);
这段代码会显示变量i 的值等于3。i 是表示返回的值,而不是创建的函数,因为括号
“(”比等号“=”有更高的优先级。这样的代码可能并不常用,但当用户想在很长的代码段
中进行模块化设计或者想避免命名冲突,这是一个不错的解决办法。
需要注意的是,尽管下面两种创建函数的方法是等价的:
function funcName(){
//函数体
}
//等价于
var funcName=function(){
//函数体
}
但前面一种方式创建的是有名函数,而后面是创建了一个无名函数,只是让一个变量指
向了这个无名函数。在使用上仅有一点区别,就是:对于有名函数,它可以出现在调用之后
再定义;而对于无名函数,它必须是在调用之前就已经定义。例如:
<script language="JavaScript" type="text/javascript">
<!--
func();
var func=function(){
alert(1)
}
//-->
</script>
这段语句将产生func未定义的错误,而:
<script language="JavaScript" type="text/javascript">
<!--
func();
function func(){
alert(1)
}
//-->
</script>
则能够正确执行,甚至下面的语句也能正确执行:
<script language="JavaScript" type="text/javascript">
<!--
func();
var someFunc=function func(){
alert(1)
}
//-->
</script>
由此可见,尽管JavaScript是一门解释型的语言,但它会在进行函数调用时,检查整个
代码中是否存在相应的函数定义,这个函数名只有是通过function funcName()形式定义的才
会有效,而不能是匿名函数。Run code
Cut to clipboard
文章:理解JavaScript构造函数 发表时间:2017-11-01, 17:04:18
#850
作者:广西南宁市
js深入理解构造函数和原型对象
1.在典型的oop的语言中,如java,都存在类的概念,类就是对象的模板,对象就是类的实例。但在js中不存在类的概念,js不是基于类,而是通过构造函数(constructor)和原型链(propotype chains)实现的。但在ES6中引入了类(class)这个概念,作为对象的模板,新的class写法知识让原型对象的写法更加清晰,这里不重点谈这个
2.首先我们来详细了解下什么是构造器
构造函数的特点:
a:构造函数的首字母必须大写,用来区分于普通函数
b:内部使用的this对象,来指向即将要生成的实例对象
c:使用New来生成实例对象
eg1:
构造函数的缺点:
所有的实例对象都可以继承构造器函数中的属性和方法。但是,同一个对象实例之间,无法共享属性
解决思路:
a:所有实例都会通过原型链引用到prototype
b:prototype相当于特定类型所有实例都可以访问到的一个公共容器
c:那么我们就将重复的东西放到公共容易就好了
eg2:

一个构造函数Person生成了两个对象实例girl和boy,并且有两个属性和一个方法。但是sayHello方法是不一样的。如上图(图画得很丑)。也就是说当New一个实例对象的时候,都会去创建一个sayHello方法,这就浪费了内存资源,因为sayHello方法使一样的行为的,完全可以被两个实例对象共享。
所以,缺点就是:同一个构造函数的对象实例之间无法共享属性和方法。
为了解决构造函数的这个缺点,js提供了prototype属相来解决该问题。
propotype属性的作用
js中每个数据类型都是对象,除了null 和 undefined(这个可以参考另一篇将null 和 undefined的博客),而每个对象都是继承自一个原型对象,只有null除外,它没有自己的原型对象,最终的Object的原型为null
eg3:

constructor属性的作用
a:分辨原型对象到底是哪个构造函数
b:从实例新建另一个实例
c:由于constructor属性是一种原型对象和构造函数的关系,所以在修改原型对象的时候,一定 要注意construtor的指向问题,避免instanceof失真,关于这一点,会在继承中讲到。
3.了解了构造器,我们来看下原型prototype
JS中万物都是对象,但是对象也分为:普通对象和函数对象,也就是Object 和 Function.
那么怎么区分普通对象和函数对象呢? ---凡是通过New Function()创建的对象都是函数对象,其他的都是普通对象.
需要注意的是:普通对象没有propotype(prototype即是属性也是对象),但是有__proto__属性。
js创建对象的时候都有一个__propo__内置属性,用于指向创建它的函数对象的原型对象prototype。
我们还是来根据eg3的代码来分析原型链
console.log(girl.__proto__ === Person.protype);//true
console.log(Persion.propotype.__proto__ === Object.propotype);//true
console.log(Object.porpotype.__proto__); //null
通过__proto__串起来直到Object.propotype.__proto__为null的链叫做原型链(矩形表示函数对象,椭圆形表示普通对象)

也许看到这个图会有几个疑问
a:为什么Object.__proto__指向Function.prototype?
Object是函数对象,是通过new Function()创建的,所以...
b:Function.__proto__ === Function.prototype //true
Function也是对象函数,通过new Function()创建,所以...
1.在典型的oop的语言中,如java,都存在类的概念,类就是对象的模板,对象就是类的实例。但在js中不存在类的概念,js不是基于类,而是通过构造函数(constructor)和原型链(propotype chains)实现的。但在ES6中引入了类(class)这个概念,作为对象的模板,新的class写法知识让原型对象的写法更加清晰,这里不重点谈这个
2.首先我们来详细了解下什么是构造器
构造函数的特点:
a:构造函数的首字母必须大写,用来区分于普通函数
b:内部使用的this对象,来指向即将要生成的实例对象
c:使用New来生成实例对象
eg1:
function Person(name,age){
this.name = name;
this.age = age;
this.sayHello = function(){
console.log(this.name +"say hello");
}
}
var boy = new Person("bella",23);
boy.sayHello(); // bella say helloRun code
Cut to clipboard
构造函数的缺点:
所有的实例对象都可以继承构造器函数中的属性和方法。但是,同一个对象实例之间,无法共享属性
解决思路:
a:所有实例都会通过原型链引用到prototype
b:prototype相当于特定类型所有实例都可以访问到的一个公共容器
c:那么我们就将重复的东西放到公共容易就好了
eg2:
function Person(name,age){
this.name = name;
this.age = age;
this.sayHello = function(){
console.log(this.name + "say hello");
}
}
var girl = new Person("bella",23);
var boy = new Person("alex",23);
console.log(girl.name); //bella
console.log(boy.name); //alex
console.log(girl.sayHello === boy.sayHello); //falseRun code
Cut to clipboard
一个构造函数Person生成了两个对象实例girl和boy,并且有两个属性和一个方法。但是sayHello方法是不一样的。如上图(图画得很丑)。也就是说当New一个实例对象的时候,都会去创建一个sayHello方法,这就浪费了内存资源,因为sayHello方法使一样的行为的,完全可以被两个实例对象共享。
所以,缺点就是:同一个构造函数的对象实例之间无法共享属性和方法。
为了解决构造函数的这个缺点,js提供了prototype属相来解决该问题。
propotype属性的作用
js中每个数据类型都是对象,除了null 和 undefined(这个可以参考另一篇将null 和 undefined的博客),而每个对象都是继承自一个原型对象,只有null除外,它没有自己的原型对象,最终的Object的原型为null
eg3:
function Person(name,age){
this.name = name;
this.age = age;
}
Person.propotype.sayHello = function(){
console.log(this.name + "say hello");
}
var girl = new Person("bella",23);
var boy = new Person("alex",23);
console.log(girl.name); //bella
console.log(boy.name); //alex
console.log(girl.sayHello === boy.sayHello); //trueRun code
Cut to clipboard
function Person(name,age){
this.name = name;
this.age = age;
}
Person.propotype.sayHello = function(){
console.log(this.name + "say hello");
}
var girl = new Person("bella",23);
console.log(girl.construcotr); //Person()
console.log(girl.construcotr == Person.propotype.construcotr); //trueRun code
Cut to clipboard
constructor属性的作用
a:分辨原型对象到底是哪个构造函数
function Person(){};
var person1 = new Person();
console.log(person1.construcotr === Person); //trueRun code
Cut to clipboard
b:从实例新建另一个实例
function Person(){};
var person1 = new Person();
var person2 = new person1.construcotr();
console.log(person2 instanceof Person); //trueRun code
Cut to clipboard
c:由于constructor属性是一种原型对象和构造函数的关系,所以在修改原型对象的时候,一定 要注意construtor的指向问题,避免instanceof失真,关于这一点,会在继承中讲到。
3.了解了构造器,我们来看下原型prototype
JS中万物都是对象,但是对象也分为:普通对象和函数对象,也就是Object 和 Function.
那么怎么区分普通对象和函数对象呢? ---凡是通过New Function()创建的对象都是函数对象,其他的都是普通对象.
需要注意的是:普通对象没有propotype(prototype即是属性也是对象),但是有__proto__属性。
js创建对象的时候都有一个__propo__内置属性,用于指向创建它的函数对象的原型对象prototype。
我们还是来根据eg3的代码来分析原型链
console.log(girl.__proto__ === Person.protype);//true
console.log(Persion.propotype.__proto__ === Object.propotype);//true
console.log(Object.porpotype.__proto__); //null
通过__proto__串起来直到Object.propotype.__proto__为null的链叫做原型链(矩形表示函数对象,椭圆形表示普通对象)
也许看到这个图会有几个疑问
a:为什么Object.__proto__指向Function.prototype?
Object是函数对象,是通过new Function()创建的,所以...
b:Function.__proto__ === Function.prototype //true
Function也是对象函数,通过new Function()创建,所以...
文章:理解JavaScript构造函数 发表时间:2017-11-01, 16:50:44
#851
作者:广西南宁市
后者可以这么说
content-box:标准盒模型,CSS定义的宽高只包含content的宽高
border-box:IE盒模型,CSS定义的宽高包括了content,padding和border #,广西南宁市,2017-11-01,16:46:35, 为什么只是 border和padding,给设置margin为什么还是会溢出呢?
content-box:标准盒模型,CSS定义的宽高只包含content的宽高
border-box:IE盒模型,CSS定义的宽高包括了content,padding和border
文章:理解box-sizing布局 发表时间:2017-11-01, 16:46:24
#852
作者:广西南宁市
function myObject(msg){
}
myObject.name='china';
myObject.nameThis='china';
alert(myObject.name); //IE: china FF:myObject
alert(myObject.nameThis); //IE,FF: chinaRun code
Cut to clipboard
文章:理解JavaScript构造函数 发表时间:2017-11-01, 16:29:06
#853
作者:广西南宁市
当我们试图访问实例对象的属性或方法时,如果该属性或方法在此实例对象上,那么就去原型链上查找,如果原型链上没有,会再向上一级原型链上查找。
这是基于原型链实现继承中对属性和方法的访问,例子如下:
但当我们修改实例对象的属性和方法时,如果此对象的该属性或方法不存在,那么会在该对象上创建该属性,而不是修改原型链上的属性,例子如下:
原因:
根据ECMA262-3 ,当对对象O(所有javascript对象和部分宿主对象)的属性P设置值时会调用内置的[[Put]]方法:
8.6.22[[Put]]方法描述:
1.以名字 P 调用 O 的[[CanPut]]方法。
2.如果 Result(1) 为 false,返回。
3.如果 O 没有以 P 为 名的属性,转到步骤6.
4.将该属性的值设为 V 。不改变该属性的特征。
5.返回。
6.创建以 P 为名属性,将其值设为 V , 并给予它空特征。
7.返回。
不过,值得注意的是,假如 O 是一个 Array 对象,关于[[Put]]方法有更多详细叙述(15.4.5.1)。
8.6.2.3 [[CanPut]]方法执行步骤:
1.如果 O 没有以 P 命 名的属性,转到步骤4.
2.如果该属性有 ReadOnly 特征,返回 false。
3.返回 true。
4.如果 O 的[[Prototype]]为 null,返回 true。
5.以属性名 P 调用 O 的[[Prototype]]的[[CanPut]]方法。
6.返回 Result(5)。
ECMA的解释印证了我们前面例子的现象。
这是基于原型链实现继承中对属性和方法的访问,例子如下:
var Person=function(){};
//将函数原型的属性重写为stu和sayHello。
Person.prototype={
Stu:{Name:"Bill"},
sayHello:function(){
alert("Hello,I'm "+this.Stu.Name)
}
}
//实例化
var p1=new Person();
//实例本身没有sayHello方法,所以调用了原型链上的sayHello方法。
p1.sayHello();//Hello.I'm BillRun code
Cut to clipboard
但当我们修改实例对象的属性和方法时,如果此对象的该属性或方法不存在,那么会在该对象上创建该属性,而不是修改原型链上的属性,例子如下:
//实例化p2
var p2=new Person();
p2.Stu = "student";
alert(p1.Stu); //[Object object] 实例p1依然访问原型链上的Stu属性,并且原型链上的Stu属性并未被p2.Stu = "student"所影响。
alert(p2.Stu);//student 实例p2访问的Stu已经是自己的Stu属性了,p2.Stu = "student"使p2在自己的对象上创建了Stu属性。
//但是,有这样一种情况:
delete p2.Stu;//删除实例p2的Stu属性。
alert(p2.Stu);//[Object object] 说明p2自身的Stu属性已被删除,此时访问的已经是原型链上的Stu属性了。
//更改实例对象在原型链上的属性,如果按照前面的说法,p2可能会创建自己的Stu.Name属性并赋值为Martin。但实际情况是这样的,如果实例对象要修改自身的一级属性(p2.Stu = "xxx";),并且该属性不存在,那么,会在该实例对象上创建Stu属性,并修改该属性,此时,不会影响对原型链上的该属性造成影响。如果实例对象要修改自身的N(N>1)级属性(p2.Stu.Name = "xxx";),若该实例不存在N级前的N-1级中的某个属性,就会到原型链上查找该属性,若未找到,查找下一级原型链,如果到最后都没有找到,给出TypeError错误,如果找到了,那么就在该原型链上修改此属性,例子如下:
p2.Stu.Name="Martin";//自身不存在Stu属性,访问原型链,原型链上存在,修改该原型链上的该属性,当然,这里只是一级原型链,也可能是二级或者N级。
p1.sayHello();//Martin 说明原型链已被修改
p2.sayHello();//Martin 说明原型链已被修改
p2.Teacher.Name = "jack";// TypeError: Cannot set property 'Name' of undefined 实例和原型链上都不存在Teacher属性,无法赋值。Run code
Cut to clipboard
原因:
根据ECMA262-3 ,当对对象O(所有javascript对象和部分宿主对象)的属性P设置值时会调用内置的[[Put]]方法:
8.6.22[[Put]]方法描述:
1.以名字 P 调用 O 的[[CanPut]]方法。
2.如果 Result(1) 为 false,返回。
3.如果 O 没有以 P 为 名的属性,转到步骤6.
4.将该属性的值设为 V 。不改变该属性的特征。
5.返回。
6.创建以 P 为名属性,将其值设为 V , 并给予它空特征。
7.返回。
不过,值得注意的是,假如 O 是一个 Array 对象,关于[[Put]]方法有更多详细叙述(15.4.5.1)。
8.6.2.3 [[CanPut]]方法执行步骤:
1.如果 O 没有以 P 命 名的属性,转到步骤4.
2.如果该属性有 ReadOnly 特征,返回 false。
3.返回 true。
4.如果 O 的[[Prototype]]为 null,返回 true。
5.以属性名 P 调用 O 的[[Prototype]]的[[CanPut]]方法。
6.返回 Result(5)。
ECMA的解释印证了我们前面例子的现象。
文章:理解JavaScript构造函数 发表时间:2017-11-01, 16:27:59
#854
作者:广西南宁市
<script>
var a = 5;
(a > 0) ? (alert("这是正整数"),document.title="也是自然数") : alert("这是负数");
</script>Run code
Cut to clipboard
碰到这种情况你可以用小括号和逗号
{} 花括号是创建对象字面量的符号,而对象是由若干个 "名/值"对组成的集合 对象的属性名与属性值之间由冒号连接 所以这里JS认为你要创建一个对象,可对象里又找不到冒号
文章:JavaScript简写技巧 发表时间:2017-11-01, 15:58:25
#855
作者:广西南宁市
最后一点 ~~ 刚知道,那parseInt也可以用 ~~ 了。
就是if的时候要注意,比如
要考虑variable1为0的时候,因为当0 的时候 ,上下两个语句是不一样的结果。
就是if的时候要注意,比如
if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
let variable2 = variable1;
}
const variable2 = variable1 || 'new';Run code
Cut to clipboard
要考虑variable1为0的时候,因为当0 的时候 ,上下两个语句是不一样的结果。
文章:JavaScript简写技巧 发表时间:2017-11-01, 15:51:24
1,reload 方法,该方法强迫浏览器刷新当前页面。 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前页。true, 则以 GET 方式,从服务端取最新的页面, 相当于客户端点击 F5("刷新") 2,replace 方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,你不能通过“前进”和“后退”来访问已经被替换的URL。 语法: location.replace(URL) 通常使用: location.reload() 或者是 history.go(0) 来做。 此方法类似客户端点F5刷新页面,所以页面method="post"时,会出现"网页过期"的提示。 因为Session的安全保护机制。 当调用 location.reload() 方法时, aspx页面此时在服务端内存里已经存在, 因此必定是 IsPostback 的。 如果有这种应用: 需要重新加载该页面,也就是说期望页面能够在服务端重新被创建,期望是 Not IsPostback 的。 这里,location.replace() 就可以完成此任务。被replace的页面每次都在服务端重新生成。 代码: location.replace(location.href); 返回并刷新页面: location.replace(document.referrer); document.referrer //前一个页面的URL 不要用 history.go(-1),或 history.back();来返回并刷新页面,这两种方法不会刷新页面。<a href="javascript:history.go(-1);">后退</a> <a href="javascript:history.go(1);">前进</a>Javascript:history.go()和history.back()的用法和区别
go(-1): 返回上一页,原页面表单中的内容会丢失;history.go(-1):后退+刷新;history.go(1) :前进
back(): 返回上一页,原页表表单中的内容会保留; history.back():后退 ; history.back(0) 刷新; history.back(1):前进
不同的浏览器的后退行为也是有区别的,而区别就跟Javascript:history.go()和history.back()的区别类似。
chrome和ff浏览器后退页面,会刷新后退的页面,若有数据请求也会提交数据申请。类似于
history.go(-1)
而safari(包括桌面版和ipad版本)的后退按钮则不会刷新页面,也不会提交数据申请。类似于
Javascript:history.back()。
windows.location.reload();//刷新
windows.location.forward;前进