编程 51

当1个JavaScripter初次进入PHP的社会风气,Javascript基础学习

By admin in 编程 on 2019年5月6日

 本文将从以下11点介绍javascript和PHP在基础语法和基本操作上的异同:

1.null和undefined

1.数据类型的异同

①概念上区别:

2.常量和变量的定义的不同,字符串连接运算符不同

  null是一个特殊的对象,是“非对象”,使用typeof后是object对象

3.对象的创建方法的不同

  undefined用未定义的值表示更深层次的“空值”,它是变量的一种取值,表示变量没有初始化。使用typeof后是undefined,undefined是预定义的全局变量(和null不同,null是关键字)

4.PHP与JS在变量声明提升和函数声明提升的差异

 

5.var在JS和PHP中使用的差异

  null表示”没有对象”,即该处不应该有值。

6.PHP和JS在访问对象属性时候使用的操作符不同

  undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。

7.类型检测的方式不同

②使用场景上:

8.论PHP和JS打印变量的方式的对比

  null类型也只有一个值,即null。null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。

9.PHP和JS中函数作用域和全局作用域的关系

  null表示”没有对象”,即该处不应该有值。典型用法是:

10.引用传递还是值传递?

  (1) 作为函数的参数,表示该函数的参数不是对象。

11.JS和PHP对
“数组 ==数组”这一表达式截然不同的对待

  (2) 作为对象原型链的终点。

 

      Object.getPrototypeOf(Object.prototype)
      // null

编程 1

 
undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:

1.数据类型不同

 (1)变量被声明了,但没有赋值时,就等于undefined。

JS基本类型:string,number,boolean,null,undefined
引用类型:object, array,function,

 var i;
 i    // undefined

(date,RegExp)

 (2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。

PHP:标量类型:string,float,integer,Boolean,复合类型:object,array
特殊类型:null,Resource

function f(x){console.log(x)}
f() // undefined

【注意】

 (3)对象没有赋值的属性,该属性的值为undefined。


PHP里没有Function类型和undefined类型!虽然PHP定义和使用的函数和JS类似,但在这里函数在类型上只能归为Object类型。同时undefined类型也是不存在的

var  o = new Object();
o.p // undefined


Resource即资源类型变量,它保存有为打开文件、数据库连接、图形画布区域等的特殊句柄

 (4)函数没有返回值时,默认返回undefined。

 编程 2

var x = f();
x // undefined

2.常量和变量的定义不同,字符串连接运算符不同

 

对JS变量定义:var
A =1 或let A =1; 常量定义:const A = 1;(ES6)

2.全局对象

对PHP变量定义:在变量名称前加$
常量定义: define(变量名称[字符串], $value[常量的值])

  全局对象(global object)在JavaScript中有着重要的用途:

<?php
   define('a', '我是常量');//定义常量
   $b = '我是变量'//定义变量
?>

  全局对象的属性是全局定义的符号,JavaScript程序可以直接使用。当JavaScript解释器启动时候,它将创建一个新的全局对象,并定义一组初始属性。

【注意】在PHP中使用变量和常量的区别在于变量在需要在前面加$,常量不需要

  在代码的最顶级——不在任何函数内的Javascript代码——可以使用Javascript关键字this来引用全局对象。

 

  var global = this;

字符串连接要用“.”操作符而不是“+”操作符

  在客户端Javascript当中,在其表示的浏览器窗口中的所有javascript代码中,window对象充当了全局对象,这个全局Window对象有一个属性window引用其自身,可以代替this来引用全  
 局对象。

JS:var str =
‘外婆的’ + ‘彭湖湾’;

  初次创建的时候,全局对象定义了Javascript中所有的预定义全局值。这个特殊对象同样包含了为程序定义的全局值。如果代码声明了一个全局变量,这个全局变量就是全局对象的一个属性。

PHP:在PHP中连接字符串时候,我们不能像JS中使用我们喜闻乐见的“+”运算符了

 

<?php
   var_dump( '外婆的'+'彭湖湾');
?>

3.包装对象

运行结果:

  存取字符串、数字或者布尔值的属性时创建的临时对象称为包装对象。

 编程 3

  理解:

如你所见,当你试图这样做的时候,它只会返回0

  我们在使用JS的时候,经常遇到下面的情况: 

而当你改成:

1  var s = 'Hello World!';
2  s.len = 12; //这个对象是临时的,所以下句代码执行后为undefiend
3  alert(s.len);
<?php
      var_dump( '外婆的'.'彭湖湾');
?>

  s是一个字符串,并不是一个对象,为什么能使用s.len这个属性呢?

 编程 4

  原因:在调用s.len时候,会使用new String(s)创建一个临时的对象,这个对象继承了字符串的方法和属性。

 

  同理数字和布尔值也可以通过Number()和Boolean()来构造一个临时的对象。

 

  注意:

3.对象的创建方法不同——在PHP中你无法使用在JS中司空见惯的对象字面量

  ①下面执行的结果是:test类型时string,而test2的类型时object

JS中你可以这样定义对象var
person = {name:’penghwuan’}

1  //打印两者的类型,发现test是字符串,而test2则为object类型
2  var test2 = new String(test);
3  alert(typeof (test) + " " + typeof (test2));

②   
1  //test和test2在使用==时候是相等的,但是使用===就不同了
2   if (test == test2) {
3       alert("他们一样!");
4   }
5   else {
6       alert("他们不一样!");
7   }
8 
9  if (test === test2) {
10     alert("他们一样!");
11 }
12 else {
13     alert("他们不一样!");
14 }
             

在PHP中上述做法是种语法错误:

4.不可变的原始值和可变的对象引用

<?php
   $obj = {name:'penghwuan'};
   var_dump($obj);
?>

  这个有点像C#当中的值类型和引用类型,还涉及了C#当中字符串的不可变性

 编程 5

  JS当中的原始值包括:布尔型、数字、字符串、null、undefined

 

  JS当中的对象类型包括:数组、对象等

如果你非要用对象字面量呢?你可能要这样用:(下面只是示范,不推荐)

  ①两者的变化性是不同的

<?php
    $obj_text = '{"name":"penghwuan"}';//定义一个字面量形式的字符串
    $obj = json_decode($obj_text);//将字符串解析成JSON对象
    var_dump($obj);//打印对象
?>

  原始值是不可变的,对于布尔、数字、null和undefined这几个类型比较容易理解,但是对于字符串涉及到了字符串的不可变性。

运行结果:

  例如:  

 编程 6

1 var str = "hello";
2 str.toUpperCase();
3 alert(str);

那么在PHP中应该怎么创建对象呢?——定义一个类并实例化对象

  结果是打印了hello。

<?php
    class obj {
      var $name = '彭湖湾';//定义成员变量
      var $hometown = '广东梅州';//定义方法
        public function get_name(){
            return $this->name;
          }
       }
      $person = new obj;//实例化对象
      $hometown = $person->hometown;//通过对象访问成员变量
      $name = $person->get_name();//通过对象调用方法
      echo '我叫'.$name;
      echo "<br/>";
      echo '我来自'.$hometown;
?>

  对象的值是可以修改的。

 编程 7

例如:
1   //对象值可变
2   var object1 = { x: 1, y: 2 };
3   object1.x = 10;  //修改一个属性值
4   object1.z = 12;  //增加一个属性值
5   alert(object1.x + "......" + object1.z);
6 
7 
8   var array1 = [1, 2, 3];
9   array1[0] = 10; //修改一个数组的值
10  array1[3] = 4;   //增加一个数组的值
11  alert(array1[0] + "......" + array1[3]);

 

  输出结果:

4.变量声明提升和函数声明提升

编程 8 
  编程 9

JS中最让我们印象深刻的特点是它变量声明提升和函数声明提升的特点,在解析所有代码前,编译器会优先将所有的函数声明和变量声明执行一遍,然后再执行具体的代码。

  ②两者的比较也不一样

JS:存在变量和函数声明提升

  1)原始值的比较就是值的比较:只有在它们值相等时候它们才相等。对已字符串如果它们的长度相同,并且每个索引的字符都相等,则认为它们相等

首先先说一下变量声明提升,而在这之前,先问大家一个问题,如果我们输出一个没有定义的变量会怎么样?

  2)对象值的比较不是值的比较,即使两个对象包含同样的属性和相同的值,它们也是不相等的。各个索引元素完全相等的两个数组也不是相等的。

<script type="text/javascript">
   console.log(bless);//输出一个尚且不存在的变量
</script>
例如:
1  //对象的比较
2   var object2 = { x: 1 };
3   var object3 = { x: 1 };
4   alert(object2 == object3); //输出是false
5 
6   var a = [1];
7   var b = [1];
8   alert(a == b); //输出是false
9 
10  //当两个对象指向同一个基对象时候它们才相等
11  var x = [];
12  var y = x;        
13  x[0] = 1;
14  alert(y[0]);       //输出结果为1
15  alert(x == y);   //输出结果为true

运行:

  上面代码所示var
y = x;仅仅是把x的引用赋值给了y,如果想得到一个引用类型的副本,就必须显示地进行赋值对象的每一个属性或者数组的每一个元素。(循环的方式)

编程 10

  同理引用类型的比较也必须显示的比较每一个属性或者元素。

没错,会抛出变量未定义的错误。如果我在输出语句的下方加个声明呢?

 

<script type="text/javascript">
    console.log(bless);//输出一个尚且不存在的变量
    var bless = '鸡年大吉'
</script>

  5.类型转换

根据猜测,可能的结果三种:

  JS中的类型装换会根据需要进行转换,非常灵活。不想其他高级语言会有错误的提示。

1还是报错

  编程 11

2打印undefined

  1)转换和相等性:一个值转换成另一个值,并不意味着这两个值相等。

3打印“鸡年大吉”

  例如:在期望使用布尔值的地方使用了undefined,它会转换成false,但是这并不表明undefined == false。

 

  2)显示类型转换

demo:

  做显示类型转换最简单的方法就是使用以下的函数:

编程 12

  Number()

结果是undefined,已经不会报错了,但也并没有被赋值为“鸡年大吉”,这告诉我们两个结论:

  Boolean()

1.JS中存在变量声明提升,var声明的变量会被提升至代码顶部执行(在下方声明后不报未定义的错了)

  String()

2.JS中虽然存在变量声明提升,但赋值操作却不能被提升(输出undefined而不是鸡年大吉)

  Object()

根据上述两点的结论,

  注意:除了null和undefined之外的任何值都具有toString()方法,这个方法的执行结果和String()一致。

console.log(bless);//输出一个尚且不存在的变量

 

var bless
= ‘鸡年大吉’

  数字转换成字符串(number-to-string)

等价于:

  有几个方法需要了解

var
bless;//变量声明被提升

  toString()方法

console.log(bless);//输出一个尚且不存在的变量

例:
1  var num = 100;
2  var bin = num.toString(2);//二进制
3  var oct = num.toString(8);//八进制
4  var hex = num.toString(16);//十六进制
5 
6  alert(bin + "..." + oct + "..." + hex);

bless =
‘鸡年大吉’;//赋值操作未被提升

编程 13

再说一下函数变量提升:

 
处理科学计算数据的时候,可以使用以下方法

<script type="text/javascript">
   send_bless();
   function send_bless(){
     console.log('祝你鸡年大吉吧!')
    }
</script>

  ①toFixed()方法

在声明一个函数前调用这个函数

  根据小数点后的指定位数将数字转换为字符串。

编程 14

  ②toExponential()

这就是函数声明提升

  使用指数方式进行记录,小数点钱只有一位

 

  ③toPrecision()

PHP:对PHP,存在函数声明提升,但不存在变量声明提升,让我们看一下下面这个例子:

 
根据指定的有效数字位数将数字转换成字符串。如果有效位数少于数字整数部分的位数,则转换成指数形式

<?php
        echo $bless;//提前输出变量
        send_bless();//提前调用函数
         $bless = '鸡年大吉';//定义变量
        function send_bless(){//通过声明方式定义函数
           echo '祝你鸡年大吉吧'."<br/>";
        }
?>

  例:  

 

1  var n = 123456.789;
2  alert(n.toFixed(0) + "..." + n.toFixed(2) + "..." + n.toFixed(5));
3  alert(n.toExponential(1) + "..." + n.toExponential(3));
4  alert(n.toPrecision(4) + "..." + n.toPrecision(7) + "..." + n.toPrecision(10));

结果是什么呢?

 编程 15 编程 16 编程 17

 编程 18

  注意结果,它们都进行了4舍5入

这告诉我们,PHP里面存在函数声明提升,而不存在变量声明提升

  将字符串转换成数字(string-to-number)

 

  ①直接使用Number()函数

5.关于var——在PHP中,你差不多可以忘记var了

 
传入一个字符串,试图将其转换成一个整数或者浮点数直接量,这个方法只能基于十进制进行转换,并且不能出现非法的尾随字符。 

我相信这三个var字母已经被无数JSer书写过无数次了,但在PHP中还能不能用var呢?能!但var已经被“打入冷宫,沦为摆设”

  ②使用parseInt()和parseFloat()方法

JS: var
变量 = 变量值

  parseInt只解析整数,而parseFloat可以解析整数和浮点数

PHP:在PHP中var只能放在类中,起到声明成员变量的作用,放在类以外的地方就会报错:

  如果字符串的前缀是“0x”或者“0X”,则解析为16进制

<?php
    var $word = '算法要学好';
    echo $word;
?>

  编程 19

 

 

运行:

  parseInt可以接受2个参数,第二参数指定了进制位数,合理取值是2-36

 编程 20

 

在类中使用就不会报错啦!

 
  编程 21

<?php
   class Person{
      var $word ='算法要学好';
    }
   $me = new Person();
   echo $me->word;
?>

 

 编程 22

 

 

对象转换成原始值

6.访问对象属性时候使用的操作符不同

①对象到boolean值

JS:使用“.”操作符

由上面最开始的图知道,所有对象转换为boolean值都是true;

<script type="text/javascript">
   var obj = {name:'彭湖湾'};
   console.log(obj.name);
</script>

对于包装对象也是如此,new
Boolean(false)是一个对象而不是原始值,转换后为true

编程 23

 

PHP:使用“->”操作符

②对象到字符串,对象到数字

<?php
    class Person{
       var $word ='算法要学好';
       function echo_word(){
          echo '数据结构也很重要';
          }
    }
    $me = new Person();
    echo $me->word;//通过->访问对象中的成员变量
    echo "<br/>";
    echo $me->echo_word();//通过->调用对象中的方法
?>

以下的转换规则只适用于本地对象,宿主对象根据自己的算法进行转换

 编程 24

 

 

所有的对象继承了两个转换方法toString()和valueof();

7.类型检测的方法不同

toString方法作用是返回一个对象的字符串,但是要注意的是很多类型定义了自己的toString方法

在类型检测的方法中,我们一般将方法分成两个思路:

例如:

思路1:检测变量属于哪种类型。(返回string)

数组:返回一个以“,”作为分隔的字符串

思路2:检测变量是否属于给定类型,(返回boolean)

函数,返回函数实现的定义

基于这一思路我来阐述JS和PHP的类型检测机制:

日期,返回一个可读的是日期时间

对JS:

RegExp类,返回一个符合正则表达式的字符串

思路1:typeof 变量
检测变量类型
,能够检测所有JS基本类型(除了null),也能检测出引用类型中的function和Object,缺陷:不能检测出Array和普通对象,而会把它们都检测为Object

 

<script type="text/javascript">
    var number =1,str ='字符串',bool =true,null_value = null,undefined_value =undefined;
    var fuc = function(){}, array = [1,2,3],obj ={};
    console.log('number的类型是',typeof number);
    console.log('str的类型是',typeof str);
    console.log('null_value的类型是',typeof null_value);
    console.log('undefined_value的类型是',typeof undefined_value);
    console.log('fuc的类型是',typeof fuc);
    console.log('array的类型是',typeof array);
    console.log('obj的类型是',typeof obj);
</script>

Valueof()

 编程 25

对象是复合值,大多数对象无法真正表示为一个原始值

从上面的例子可看出typeof的缺陷所在:不能检测出Array和普通对象,而会把它们都检测为Object;

数组,函数,正则,在调用的时候,都会返回对象的本身,而不是一个原始值

 

日期 会返回一个毫秒数

【吐槽】:正所谓学而不思则罔,就在复习这个知识点的时候,我发现了一个极其有趣的现象!:null检测的类型是object!!是object!!!!

 

我还在知乎上找到了这样一段答案:

JS当中对象到字符串的转换过程:

 

1)先调用toString(),如果返回一个原始值就把这个值转成字符串返回

编程 26

2)否则调用valueof(),如果成功返回一个原始值,就转换成字符串返回

编程 27 

3)都不行,就抛出异常

思路2:[变量
instanceof 类型] 能分别检测出array,普通object和function

 

<script type="text/javascript">
    var fuc = function(){}, array = [1,2,3],obj ={};
    console.log('fuc的类型是Function',fuc instanceof Function);
    console.log('array的类型是Array',array instanceof Array);
    console.log('obj的类型是Object',obj instanceof Object);
    console.log('fuc的类型是Object',fuc instanceof Object);
    console.log('array的类型是Object',array instanceof Object);
</script>

JS当中对象到数字的转换

 

和对象到字符串的转换过程稍微有一点不同,他是先进行valueof()调用,返回一个原始值,那么就转换成数字返回。如果没有返回原始值,就再调用toString()。

编程 28 

解释:为什么空数组会被转换成数字0?

对PHP:

1)首先空数组调用valueof()函数,它返回的是一个对象而不是一个原始值,然后再调用toString(),空数组转化成空字符串进行返回,空字符串转换数字就是0。(可以看最开始的表)

 

 

思路1:gettype(变量)
能区分出任意数据类型

6.变量的声明

 

这个没啥讲的,var,弱类型,初始化不赋值,就是undefined

<?php
   class class_test{};
   $obj = new class_test();
   $array_test = [1,2,3];
   $string_test = '字符串';
   $int_test = 1;
   $float_test = 1.2;
   var_dump(gettype($obj));//检测对象
   echo "<br/>";
   var_dump(gettype($array_test));//检测数组
   echo "<br/>";
   var_dump(gettype($string_test));//检测字符串
   echo "<br/>";
   var_dump(gettype($int_test));//检测数组
   echo "<br/>";
   var_dump(gettype($float_test));//检测字符串
?>

 

 编程 29

7.变量的作用域

思路2:is_array()、is_bool()、is_float()、is_integer()、is_null()、is_numeric()、is_object()能检测任意数据类型

一个变量的作用域(scope)是程序源代码中定义这个变量的区域。 

<?php
    class class_test{};
    $obj = new class_test();
    $array_test = [1,2,3];
    $string_test = '字符串';
    $int_test = 1;
    $float_test = 1.2;
    var_dump(is_object($obj));//检测对象
    echo "<br/>";
    var_dump(is_array($array_test));//检测数组
    echo "<br/>";
    var_dump(is_string($string_test));//检测字符串
    echo "<br/>";
    var_dump(is_integer($int_test));//检测数组
    echo "<br/>";
    var_dump(is_float($float_test));//检测字符串
    echo "<br/>";
    var_dump(is_numeric("12"));//检测是否为数字字符串或数字
    echo "<br/>";
?>

变量根据作用域的不同可以分为,全局变量和局部变量,特有意思的是JS当中全局和局部变量可以同名,这在其他高级语言里面都是不能的。

编程 30

 

 

在函数体内,局部变量的优先级高于全局变量。

编程,8.论打印变量的方式:

例如:
    var s = "Global";
    function checkscope() {
        var scope = "Local";
        return scope;
    }
    alert(checkscope());

JS:console.log()打印基本类型的值,遇到对象或数组则打印对象属性或数组元素

  编程 31

PHP:一般有几种选择方式:

 
这里要注意一点:我们在编写全局作用域的时候可以不写var语句,但是声明局部变量时候必须使用var语句。

1.echo(注意这TM可能是个坑):只能打印标量:数字,字符串或布尔值,打印object或Array会报错,而且打印布尔值的时候true打印1,false时候什么也不打印

例如:
   var s = "Global";
    function checkscope() {
          s = "Local";
        return s;
    }
    alert(checkscope()+"..."+s);

2.var_dump打印更详细变量的类型和值,它在打印object或者array的时候,会连数组元素的类型和值也打印出来(更暖更贴心)

  编程 32

 

  函数定义是可以而嵌套的, 


echo:

1  var scope = "Global";
2  function checkscope() {
3       alert(scope);
4       var scope = "local";
5       function nested() {
6       var scope = "nested";
7       alert(scope);
8       return scope;
9       }
10     alert(scope);
11     return nested();
12    }
13  checkscope();

让我们来看看为什么我说它是个坑:

输出结果是:

打印Array时报类型转换的警告,但仍能打印类型

 编程 33编程 34编程 35

<?php
     $array = [1,2,3];
     echo $array;
?> 

由上图我们看到第一次输出是undefined,为什么会这样呢?这就涉及到了下面要讲的“声明提前”这个概念。

编程 36

①函数作用域和声明提前

打印object直接报错,连类型也不打印:

在C语言等一些高级语言中,可以把花括号之间的每一段代码看成具有自己的作用域,而且变量在声明他们的代码段之外是不可见的。我们成为块级作用域。在JS当中没有块级作用域这个概念。取而代之的是函数作用域,变量在声明他们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。‘

<?php
     class person{};
     $obj = new person();
     echo $obj;
?> 
例子
    function test(o)
    {
        var i = 0;
        if (typeof o == "object")
        {
            var j = 0;
            for (var k = 0; k < 10; k++) {
                console.log(k);
            }
            console.log(k);
        }
        console.log(j);
    }
    var o = new String(123);
    test(o);

编程 37

输出是

打印布尔值的时候若为true则打印1,若为false啥也不打印

编程 38

<?php
   $true_value = true;
   $false_value =false;
   echo $true_value;
   echo "<br/>";
   echo $false_value;
?>

 

 编程 39

可以看到K最后输出的值是10,说明k的作用域不仅仅是在循环内。j最后输出是0,也说明j的作用域不仅仅在if判断当中。

var_dump相比起来就良心多了:

上面那个输出undefined的例子,也能够被解释了,因为变量在整个函数体内是可见的,但是第一次alert的时候并没有被赋值,所以输出undefined。

<?php
        class class_test{
           var $value = '我是变量';
           public function fuc(){
               echo '我是方法';
           }
         }
        $obj = new class_test();
        $array_test = [1,2,3];
        $string_test = '字符串';
        $int_test = 1;
        $float_test = 1.2;
        var_dump($obj);//检测对象
        echo "<br/>";
        var_dump($array_test);//检测数组
        echo "<br/>";
        var_dump($string_test);//检测字符串
        echo "<br/>";
        var_dump($int_test);//检测整型
        echo "<br/>";
        var_dump($float_test);//检测浮点型
        echo "<br/>"; 
?>

所以上面的代码等价于把,变量的声明放在函数的顶部,所以就叫“声明提前”。

 编程 40

 

业界良心有没有!

②作为属性的变量

 

声明一个全局变量时候,相当于定义了一个全局对象的属性,当使用var进行声明变量的时候,这个属性是不能够被删除的,变量无法通过delete运算符来删除,但是去掉var,js也会创建一个全局的变量,这种方式创建的全局属性是可以进行删除的。

9.与JS相比,PHP没有作用域链的概念。

  

和JS一样,PHP也把作用域划分为函数作用域和全局作用域。但是由于PHP没有作用域链,所以函数作用域中不能访问全局作用域中的变量

③作用域链

JS:函数作用域能访问全局作用域中的变量,全局作用域不能访问函数作用域中的变量:

简单理解

1函数作用域(最外层)能访问全局作用域中的变量

http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html

<script type="text/javascript">
    var global_variable = '全局变量' ;
    function fuc(){
         console.log(global_variable);
     }
    fuc();
</script>

 

 

 

运行结果:

编程 41

2全局作用域不能访问函数作用域中的变量:

<script type="text/javascript">
   function fuc(){
      var area_variable = '局部变量'
   }
   fuc();
   console.log(area_variable);
</script>

运行:

编程 42

 

PHP:函数作用域(最外层)不能访问全局作用域中的变量,全局作用域也不能访问函数作用域中的变量

函数作用域不能访问全局作用域中的变量【友情提示:各位JSer不要因为写了太多JS就以为所有的语言都有作用域链哦~】

<?php
    //在这里我们试图在函数作用域内访问全局作用域的变量
   $variable = '变量';
   function fuc (){
     echo $variable;
   }
   fuc();
?>

 

全局作用域也不能访问函数作用域中的变量(这是当然的啦):

<?php
      //在这里我们试图在全局作用域内访问函数作用域的变量
    function fuc (){
       $variable = '函数作用域中变量';
    }
    fuc();
    echo $variable;
?>

 编程 43

所以,PHP中两个作用域间的访问只能通过函数参数这一个“接口”

 

【一张图总结以上内容】

编程 44

 

10.使用函数参数时,为引用传递还是值传递?

JS:只有值传递,没有引用传递(注意是只有值传递)

对于基本类型只有值传递

<script type="text/javascript">
    function addNum(value){
       return value = value +1;
     }
    var my_value = 1;
    addNum(my_value);
    console.log(my_value);
</script>

编程 45

输出为1而不是2,这说明,在运行函数fuc时候,仅仅是把my_value的值拷贝给一个新创建的局部变量value而已,然后对这个新变量进行操作,而不是针对原来定义的value变量

 

对于引用类型也只有值传递!【这点极易混淆!】:

在上面的例子中,可能容易让我们形成一种错误的概念,即值传递
== 对传入变量不会有影响,那是不是这样呢?

<script type="text/javascript">
    function change_obj_name(obj){
      obj.name = '不是彭湖湾'
    }
    var my_obj = {name:'彭湖湾'};
    change_obj_name(my_obj);
    console.log(my_obj.name);
</script>

运行结果:

编程 46

可能有人会想:怎么调用函数时对象的名称被修改了?!!不是说好了JS是值传递吗?

对!JS是值传递,但在这里,传递的参数并不是对象,而是对象的地址(或引用)!!也就是说虽然存储my_obj对象地址的变量把值传递给了函数中创建的局部变量obj(值传递),但这两者仍然指向堆内存中的同一个对象,所以上述例子中对象的值才被修改了。

 

PHP:既有值传递,也有引用传递(定义函数时,function
fuc($value){}是值传递,function fuc(&$value){}是引用传递)

先说说值传递:

<?php
       function add_num($value){
          $value = $value + 1;
       }
       $num = 1;
       echo $num.'  是修改前的num';
       add_num($num);
       echo "<br/>";
       echo $num.'  是修改后的num';
?>

 编程 47 

再说说PHP引用传递:(习惯C语言的同学应该很熟悉吧,其实就在参数前加个&而已啦。。。)

<?php
       function add_num(&$value){
          $value = $value + 1;
       }
       $num = 1;
       echo $num.'  是修改前的num';
       add_num($num);
       echo "<br/>";
       echo $num.'  是修改后的num';
?>

 编程 48

 

11.比较数组相等时,对待==运算符和===运算符截然不同的表现

先上结论:

对JS,数组==数组(或===)比较的是两个数组的地址,而对PHP,数组==数组(或===)比较的是两个数组的“内容”

 


js

<script type="text/javascript">
   var array1 =[1,2,3];
   var array2 =[1,2,3];
   console.log('两个数组是否相等?',array1 == array2);
   console.log('两个数组是否恒等?',array1 == array2);
</script>

编程 49

即使“内容”相等,两个数组也不相等,这说明对JS,数组==数组(或===)比较的是两个数组的地址


php:

<?php
    $array1 = [1,2,3];
    $array2 = [1,2,3];
     var_dump($array1 == $array2);
?>

 编程 50

 

【吐槽】:作为一名写JS的刚写到这里不禁说了句“卧槽!居然相等!”;

当然,作为一名写JS的,你很容易理解在PHP中数组==数组和数组===数组的区别,

对数组==数组:各个数组项对应的值相等,类型可以不同,例如“12”和12是相等的

对数组===数组,各个数组项对应的相等,类型也相同,“12”和12不相等!

<?php
    $array1 = [1,2,3];
    $array2 = [1,'2',3];
    echo "数组相等 ";
    var_dump($array1 == $array2);
    echo "数组恒等";
    var_dump($array1 === $array2);
?>

 编程 51

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 澳门新葡亰官网app 版权所有